Visual Basic Development Bookmark and Share   
 Home > Visual Basic Language > First time converting Com objects
 

First time converting Com objects

Hello all,
Hope you can help me. We are an old VB6 shop going through the learning curve of converting our existing code and ourselves to .NET. We have .Net 2003. Currently we have an application that exists in two parts. The COM object existing on our MTS server and the client object loaded on all our machines. The COM object handles the business logic and the data access. We have been slowly grinding our way through converting both parts from VB6 to .NET.

In VB6, we would have just compiled the class and install it on the MTS server. We would have then just exported the com object to be used in our client application.

In our client application, we would have just added the referrence to the com object, then call it as you would normally do.

Now comes .NET. We rewote the com object using .NET with the assistance of many hours of on-line reading. The beginning of the com object begins as follows:

Option Strict Off
Option Explicit On
Imports Microsoft.VisualBasic.Compatibility
Imports System.EnterpriseServices
Imports System.Reflection

<Assembly: ApplicationName("Estimate_NET")>
<Assembly: AssemblyKeyFileAttribute("bin\Estimate.snk")>

<System.Runtime.InteropServices.ProgId("Estimate_NET.Header")> Public Class Header
Inherits ServicedComponent
<AutoComplete()> Public Function SearchByStockCode(ByVal stockcode As String, Optional ByVal companyid As String = "L") As ADODB.Recordset
.
.
End Function

End Class


We compile this class and load it onto the MTS server. Not a problem. We then export the pointer. On our client workstations we load the pointer. In the client application, we try to add the reference to the com object, however, it errors out with a CLR error. After much reading, I have found that when including the reference, do not point to the tbl file but do a browse and browse into the program files/complus applications/ (...) and point directly to the dll.

That done and it works. Now we compile the client application and deploy it. No problem.

EXCEPT...we found a problem in the com object. Simple logic error. We fixed the com object and copied it onto the MTS server. Suddenly the client does not work! We had to rexport the com object. Load it onto our development machine. Load the client application and re-compile it. Then re-deploy it to the client.

I was under the impression that the whole point of com objects were to seperate the business logic of an application from the front end. Therefore when a change was needed on the business logic, all you had to do was change the com object and the clients would automatically be updated. This is not what happened...

What am I doing wrong? What did I miss? Was there something that I was suppose to check off that did not "Link" the com object to the client application?

Any and All help would be appreciated. Getting tired of doing all this reading.

Thanks
Mike
Michael Gisonda  Thursday, May 25, 2006 8:31 PM

I suspect the problem is that your COM object changed identity when you recompiled it. The COM object your client was trying to connect to no longer existed and a new apparently completely different COM object existed in its place - but your client didn't know anything about that new COM object.

In VB 6 this sort of problem was addressed using the Version Compatibility project property.

By default a managed code COM object's CLSID is generated based on a hash of the class name and the identity of the assembly the class is in. Also by default the AssemblyVersion attribute is set to a wildcard string (like "1.0.*").

A wild-carded AssemblyVersion attribute will cause the AssemblyVersion to change when the project is built (different languages handle wild cards differently but all of them change the assembly versionat one time or another) This causes the assembly's identity to change which in turn causes the generated CLSID to be different.

One solution would be to change the AssemblyVersion attribute to get rid of the wild-card. I'd suggest you do that anyway so you have explicit control of your Assembly version but I don't like it as a solution to your current problem.

Another solution would be to use the ComCompatibleVersionAttribute to indicate to .NET that the CLSIDs should be forced to the values generated by an earlier build. This is much like using the Version Compatibility project property in VB 6. http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.comcompatibleversionattribute.aspx

This solution is better than just fixing Assembly Version but still not ideal. Things can go unexpectedly wrong if the build can't find the old values for some reason.

A third (and, I think, most attractive) solution is to explicitly specify the CLSID in your source by decorating your COM class (or classes) with the GuidAttribute and a GUID generated specifically for the class. You can use Tools | Create GUID to generate a guid for each class that needs one. http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.guidattribute(VS.80).aspx

This last approach makes everything explicit and has the added advantage that someone reading the code can tell what CLSID your class uses instead of having to dig through type libraries and registration to find out what the generated CLSID value was.

As an aside, if you are going to do a lot of COM work in managed code I suggest you get hold of a book called ".NET and COM, The Complete Interoperability Guide" by Adam Nathan. http://www.amazon.com/gp/product/067232170X/ref=pd_bbs_2/103-3935986-9004648

Frank Boyne  Thursday, May 25, 2006 9:18 PM

I suspect the problem is that your COM object changed identity when you recompiled it. The COM object your client was trying to connect to no longer existed and a new apparently completely different COM object existed in its place - but your client didn't know anything about that new COM object.

In VB 6 this sort of problem was addressed using the Version Compatibility project property.

By default a managed code COM object's CLSID is generated based on a hash of the class name and the identity of the assembly the class is in. Also by default the AssemblyVersion attribute is set to a wildcard string (like "1.0.*").

A wild-carded AssemblyVersion attribute will cause the AssemblyVersion to change when the project is built (different languages handle wild cards differently but all of them change the assembly versionat one time or another) This causes the assembly's identity to change which in turn causes the generated CLSID to be different.

One solution would be to change the AssemblyVersion attribute to get rid of the wild-card. I'd suggest you do that anyway so you have explicit control of your Assembly version but I don't like it as a solution to your current problem.

Another solution would be to use the ComCompatibleVersionAttribute to indicate to .NET that the CLSIDs should be forced to the values generated by an earlier build. This is much like using the Version Compatibility project property in VB 6. http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.comcompatibleversionattribute.aspx

This solution is better than just fixing Assembly Version but still not ideal. Things can go unexpectedly wrong if the build can't find the old values for some reason.

A third (and, I think, most attractive) solution is to explicitly specify the CLSID in your source by decorating your COM class (or classes) with the GuidAttribute and a GUID generated specifically for the class. You can use Tools | Create GUID to generate a guid for each class that needs one. http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.guidattribute(VS.80).aspx

This last approach makes everything explicit and has the added advantage that someone reading the code can tell what CLSID your class uses instead of having to dig through type libraries and registration to find out what the generated CLSID value was.

As an aside, if you are going to do a lot of COM work in managed code I suggest you get hold of a book called ".NET and COM, The Complete Interoperability Guide" by Adam Nathan. http://www.amazon.com/gp/product/067232170X/ref=pd_bbs_2/103-3935986-9004648

Frank Boyne  Thursday, May 25, 2006 9:18 PM

You can use google to search for other answers

Custom Search

More Threads

• advice pls!
• VB and Excel
• date in format in query
• having trouble w/ "non-standard" characters - ($)
• writing to memory in VB
• How do I add a control to a form
• looking to exclude a function based on a flag
• Anonymous property assignment by property name
• Network Drive information
• Richedtextbox does not recognize the start of new paragraph