tags:

views:

167

answers:

4

I have trouble to expose a .NET assembly in COM. It seems that I must be missing some basic step because I think I followed all tutorials and documentation I found as well as common sense, but still when I do (in a test VBScript):

Set o = CreateObject("MyLib.MyClass")

It keeps saying that the object cannot be created.

Here are the steps I have done:

  1. I have simple one method dummy class with no attributes.
  2. The class is in a class library which has "Make assembly COM-visible" ticked in Visual Studio.
  3. The class library is signed.
  4. The DLL is registered via RegAsm.exe with the /codebase parameter (I don’t want / cannot add the DLL to GAC).

Just to be sure, I tried to copy the library to the same directory as the test VBScript, but it does not help.

Edit: I should have mentioned that the I can instantiate the class in COM if I put the DLL into GAC.

Edit: Resolved. I don't have a full explanation, but eventually I found out that it was caused by using:

%windir%\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe

and not the 64-bit version:

%windir%\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe

I compared the generated registry keys of the two RegAsm's, and they were the same. So guessing that they generate something else than the registry keys.

+2  A: 

you should add several attributes:

for interface:

[Guid("4200ead6-8252-412c-8c7e-c3b586ac40d6")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]

for class:

[Guid("9f718717-bc09-48f1-8ab1-00fa3abf4147")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyLib.MyClass")]
Andrey
You'll want to make the GUID _unique_
Charlie Somerville
yes!! this is my GUIDs, don't use them :)
Andrey
Thank you for the response. I just tried that, but it did not help.
Jan Zich
These attributes are not strictly necessary, but are nice to have because they give you more control. The main thing is to make sure the assembly/class etc has the ComVisible(true) attribute.
ShellShock
+1  A: 

You can use the Microsoft Fusion Logger http://msdn.microsoft.com/en-us/library/e74a18c4.aspx to find out why your assembly fails to load (or bind as it is called).

ShellShock
A: 

I don't have a full explanation, but eventually I found out that it was caused by using:

%windir%\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe

and not the 64-bit version:

%windir%\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe

I compared the generated registry keys of the two RegAsm's, and they were the same. So guessing that they generate something else than the registry keys.

Jan Zich
+1  A: 

Yes, this is by design on 64-bit operating systems. A lot of COM components are in-process DLLs and are only available as 32-bit DLLs. A 64-bit program cannot load any 32-bit code. To prevent them from malfunctioning, the registry is virtualized; different programs have different views of the registry.

32-bit programs actually see the keys in HKLM\Software\Wow6432\Classes. 64-bit programs see the regular keys. This automatically avoids COM server mishaps.

.NET servers are unusual in that they can run both in 32-bit and in 64-bit mode, the JIT compiler takes care of that. What you should normally do is run both versions of Regasm.exe. The one from the Framework folder will register the server for 32-bit programs, the one from the Framework64 folder registers it for 64-bit programs.

Hans Passant