Com: HowTo call .NET from COM

How do you register a .NET assembly for being callable from COM like from VB6?

Lets say you have a assembly called MyLib.dll.

Inside you have a namespace called MyNs.MyLib and a class called MyCls.

You would then add some Code

AssemblyInfo.cs

 /* Hardcode version of assembly, so the right one will be found. Ex:
 [HKEY_CLASSES_ROOT\CLSID\{0121542D-85D0-3755-AE0B-E5EBC23CF162}\InprocServer32]
"Assembly"="MyLib, Version=1.0.2300.1, Culture=neutral, PublicKeyToken=null" */

 [assembly: AssemblyVersion("1.0.2300.1")] //this attribute is found in: Project - properties - Application - Assembly info – Version
 [assembly: ComVisibleAttribute(true)] //this attribute is found in: Project - properties - Application - Assembly info - Make COM-visible
 /* Hardcode guid which is used for locating tlb. Ex:
 C:\MySln\MyLib\bin\Debug\MyLib.tlb which is written into key: 
HKEY_CLASSES_ROOT\TypeLib\{BC63BF34-85E0-3E35-84D2-93F4C88B4EA1}\1.0\0\win32 */

 [assembly: GuidAttribute("BC63BF34-85E0-3E35-84D2-93F4C88B4EA1")] //this attribute is found in: Project - properties - Application - Assembly info – GUID

Note: You will need to generate a new GUID for your assembly/library.

MyCls.cs

using System.Runtime.InteropServices; //for GuidAttribute
namespace MyNs.MyLib
{
 /* Hardcode guid which is used for locating assembly. Ex:
 [HKEY_CLASSES_ROOT\CLSID\{0121542D-85D0-3755-AE0B-E5EBC23CF162}\InprocServer32]
 "Assembly"="MyLib, Version=1.0.2300.1, Culture=neutral, PublicKeyToken=null" */
 [GuidAttribute("0121542D-85D0-3755-AE0B-E5EBC23CF162"), ProgId("MyNs.MyLib.MyCls")]
 /*AutoDispatch avoids version dependency, since the method will not be visible at design time and thereby only latebinding can be used.AutoDispatch is default so this attribute is not needed when using REGASM to register. When using TLBEXP the default is AutoDual. */
 [ClassInterface(ClassInterfaceType.AutoDispatch)]
 public class MyCls //Class name is used as ProgId in Com. Ex: [HKEY_CLASSES_ROOT\MyNs.MyLib.MyCls]
 {
  public MyCls() // public default ctor to support COM activation. Alternaltively use static ctor
  {}
 }
}

Note: You will need to generate a new GUID for your class.

Register .NET components for COM

From  Visual studio (when working in development environment)

  • Set Project – properties – Build – Register for COM. //This sets the above mentioned flag in AssemblyInfo.cs
  • Build project. //This automaticly generates a .reg file and adds it to registry.

Or from CMD – prompt (when you deploy) deployMyLib.bat

//cd to directory containing assembly
cd C:\MySln\bin\release

//optionally unregister old component before reregistering:
//%windir%\Microsoft.NET\Framework\v2.0.50727\REGASM /u MyLib.dll /tlb:MyLib.tlb /codebase /nologo

//create typelibrary and register it in registry with a path to the dll (codebase)
%windir%\Microsoft.NET\Framework\v2.0.50727\REGASM MyLib.dll /tlb:MyLib.tlb /codebase /nologo

//create .reg file to easily examine GUIDs (see below)
%windir%\Microsoft.NET\Framework\v2.0.50727\REGASM MyLib.dll /regfile:MyLib.reg /codebase /nologo

The generated MyLib.reg

[HKEY_CLASSES_ROOT\MyNs.MyLib.MyCls]
@="MyNs.MyLib.MyCls"

[HKEY_CLASSES_ROOT\MyNs.MyLib.MyCls\CLSID]
@="{0121542D-85D0-3755-AE0B-E5EBC23CF162}"

[HKEY_CLASSES_ROOT\CLSID\{0121542D-85D0-3755-AE0B-E5EBC23CF162}]
@="MyNs.MyLib.MyCls"

[HKEY_CLASSES_ROOT\CLSID\{0121542D-85D0-3755-AE0B-E5EBC23CF162}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="MyNs.MyLib.MyCls"
"Assembly"="MyLib, Version=1.0.2300.1, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="file:///C:/MySln/bin/release/MyLib.dll"

[HKEY_CLASSES_ROOT\CLSID\{0121542D-85D0-3755-AE0B-E5EBC23CF162}\InprocServer32\1.0.2300.1]
"Class"="MyNs.MyLib.MyCls"
"Assembly"="MyLib, Version=1.0.2300.1, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v2.0.50727"
"CodeBase"=file:///C:/MySln/bin/release/MyLib.dll

[HKEY_CLASSES_ROOT\CLSID\{0121542D-85D0-3755-AE0B-E5EBC23CF162}\ProgId]
@="MyNs.MyLib.MyCls"
[HKEY_CLASSES_ROOT\CLSID\{0121542D-85D0-3755-AE0B-E5EBC23CF162}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF28}]

You might notice that the methods will not be registered. This does not mean that they are not reachable. This is actually an advantage. It makes it possible to add more methods and change their signatures without rebuilding the COM client or reregister the .NET COM server. This releaves some of the DLL hell problems.

COM client

Now call you component from COM (ASP, VBScript, VB6 etc.).

You must browse to the .tlb file to get a referece to it.

Tip: You can upgrade a VB6 component MyVbLib.dll to MyVbLib.NET.dll. Your new obj from COM might be  MyVbLib_NET.MyCls and your old obj will be MyVbLib.MyCls.

 Dim myObj As MyLib.MyCls
 Set myObj = CreateObject("MyNs.MyLib.MyCls") 'Notice: Must match ProgId
 'Set myObj = New MyLib.MyCls 'Alternative, when reference has been added
 myObj.MyMethod(myParm)
 Set myObj = Nothing

The End.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: