How do I make a C# DLL into a COM interop DLL that can be consumed by a VB6 application?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Generic Generics in Managed C++
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
Microsoft has a quick how to here. However, you'll need to register the dll. To make your C# dll more like a simple C dll (C# Unmanaged Exports), use this method, which gets described in detail here.
This is the answer I wanted to find in StackOverflow but couldn't. It turns out to be fairly easy to turn a simple C# dll into a COM dll.
To create the C# dll
Create a solution with a C# class project. The class should have an interface for the properties/methods and an interface for the events. Assign GUID attributes to the class and interfaces as described in MSDN - Example COM Class (C# Programming Guide). Also see: MSDN - How to: Raise Events Handled by a COM Sink.
In Project Properties > Application tab > Assembly Information button > check "Make assembly COM-Visible". This makes all public methods in the class COM visible.
In Project Properties > Build tab > Set "Platform target" to x86.
That's all you need to do to create the DLL. To call the DLL, you need to register it.
Registering the DLL on your development machine
You can register the DLL one of these ways:
Manually register the DLL with RegAsm. This allows you to register the DLL in the directory of your choice, rather than in the build directory. This is the method I used.
Open a command shell with administrator rights and type
RegAsm.exe can be found in "C:\Windows\Microsoft.NET\Framework\v2.0.50727", while "mydll.dll" is the name of your DLL;
tlb
means "create a type library";codebase
means "write the directory location to the Registry, assuming it is not being placed in the GAC".RegAsm will display a warning that the assembly should be strong-named. You can ignore it.
At this point, you should be able to add a reference to the COM DLL in VB6, see it with Intellisense, and run it just like a regular COM DLL.
Installing the DLL with InstallShield
If you are using InstallShield to install the DLL along with the rest of your application, do the following.
In InstallShield, add a new Component to the Components list. Remember to associate the Component with a Feature. Set component property ".NET COM Interop" to Yes.
Add the .dll file to the Files section of the Component. Do not check the "Self-Register" property. Right-click on the .dll file and select "Set Key File".
Add the .tlb file to the Files section of the Component. Check the "Self-Register" property.
The correct version of the .Net Framework needs to exist on the target PC.
That's it.
As en extension to @Kieren Johnstone's answer a practical code example on class modifications you need to do:
From:
To:
Hope this saves you some time
Most examples in the internet of COM servers contain only one CoClass, and it is claimed that this CoClass must have a public constructor. This is true in this case, but normal servers have more than one CoClass, of which only one can be created, whereas the instances of the non-creatable CoClasses are properties of the creatable CoClass. For example, consider the Word object model with the creatable CoClass
Application
that has theDocuments
property which in turn consists of instances of the CoClassDocument
. The following server has two CoClasses, one with a public constructor and one with a private constructor.Create a solution for a C# Class Library (.Net Framework), not Class Library (.Net Standard) and name it for example BankServerCSharp. Choose this name wisely, because it will be the main part of the ProgIDs of your CoClasses and the namespace name in C++. This name will also be listed in the References dialog box of C# and VBA.
Delete the boilerplate code and add two files Bank.cs and Account.cs. Insert the following code:
Build the project with the configuration Release/Any CPU. The output is the managed DLL BankServerCSharp.dll located in the \bin\release folder.
Now you must register your managed COM DLL. Don't try regsvr32, there is a special program called regasm for managed COM DLLs. Regasm has a version for 32-bit and for 64-bit apps. Open a command prompt as administrator and change to C:\Windows\Microsoft.NET\Framework\v4.0.30319. This folder contains the regasm.exe app to register the managed COM DLL as if it would be a native 32-bit COM DLL.
Type
RegAsm.exe /tlb /codebase path_to_your_bin_release_folder\BankServerCSharp.dll
. You must register your DLL on any computer in this way. Don’t forget the /tlb switch that creates the type library. The compiler will comment the switch /codebase with some warnings that you can ignore. The DLL is registered in the WoW64 part of the registry and can be used by native (unmanaged) 32-bit apps.Now repeat the registration for usage of the managed COM DLL by 64-bit apps. Change to C:\Windows\Microsoft.NET\Framework64\v4.0.30319 and type the same command as before.
You can speed up the registration on your own PC by running Visual Studio with administrative rights and adding the following post-build events:
You can now use your DLL like a native unmanaged COM DLL. Test your DLL with VBA: Under Tools/References tick BankServerCSharp. If it is not shown, the registration failed. A simple test sub:
To test your managed COM DLL in C++, create a new Console Application, insert the following code and build as Release/x64 or Release/x86:
COM Interop is a technology included in the .NET Framework Common Language Runtime (CLR) that enables Component Object Model (COM) objects to interact with .NET objects, and vice versa. COM Interop aims to provide access to the existing COM components without requiring that the original component be modified and vice-versa. More at: http://www.writeulearn.com/com-interop-using-csharp/