Monday, 21 March 2011

Creating a COM Visible C# Component

If you want to expose a C# Class to COM you'll need to use the System.Runtime.InteropServices namespace. Then you need to create an interface and implement this interface in your class. Next add attributes to your interface and class to inform the compiler these should be exposed and finally, you set the properties of your component to make the assembly COM visible and register for COM interop on output.

In more detail, first add the following line to the top of your class to include the InteropServices namespace:

using System.Runtime.InteropServices;

All COM components need a globally unique identifier (a GUID) in order to be registered and used. Visual Studio can create a GUID for you. Click the Create GUID item in the Tools menu and select the fifth option which will format the line exactly as it's required for COM Interop.

Create GUID Dialog Box

Then hit the Copy button and paste the GUID into your code file below the namespace declaration but before the class declaration. Below that you need to create the interface for your component.

[Guid("5715C11C-55E8-45B4-9372-FD0FD9AA6F7C")] public interface IMyComponent { void Initialise(double version); int Add(int num1, int num2); double Version { get; set; } }

Now you need to create a new GUID for your actual class which will implement the interface. This is done in exactly the same way as you did for the interface, if the Create GUID dialog box is still open ensure you click the New GUID button in order to create a unique GUID. You mustn't use the same GUID.

Add the line just before your class declaration. This time however, you need to add extra information to the attribute. You must add a ClassInterface of None, and a ComSourceInterface that points back to your interface. Here is an example of what it should look like:

[Guid("92D467E4-F6B7-4B88-8B87-00CF78794852"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IMyComponent))] public class MyComponent

Finally, as far as code is concerned, you need to implement the interface. Here is a complete code listing of an example COM exposed class:

using System.Runtime.InteropServices; namespace MyComComponent { [Guid("5715C11C-55E8-45B4-9372-FD0FD9AA6F7C")] public interface IMyComponent { void Initialise(double version); int Add(int num1, int num2); double Version { get; set; } } [Guid("92D467E4-F6B7-4B88-8B87-00CF78794852"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(IMyComponent))] public class MyComponent : IMyComponent { public double Version { get; set; } public void Initialise(double version) { this.Version = version; } public int Add(int num1, int num2) { return num1 + num2; } } }

Now you need to actually mark the assembly as COM visible. To do this, open the project's properties and under the Application tab click the Assembly Information... button, then tick the Make assembly COM-Visible checkbox.

Assembly Information DIalog Box

Visual Studio can automatically register the type library for you after compiling the component. In order to enable this option, open the Build tab of the project's properties and tick the Register for COM interop check box.

Project properties build tab showing the Register for COM interop option checked.

If you don't want Visual Studio to automatically register for COM interop, you'll need to use the regasm command to create a COM compatible type library. To do this, open the Visual Studio Command Prompt, type in regasm followed by the full path to your dll (if you're not already in the correct folder) and then add /tlb to the end. You should see a message stating the types were registered successfully.

Visual Studio Command Prompt shown registering the assembly for COM Interop using the regasm command.

Finally, if your assembly contains multiple interfaces and classes, you can hide the ones you don't want to expose via COM. To do this simply specify false in the ComVisible attribute before the class or interface declaration.

[ComVisible(false)] public class HiddenClass

And that's it. An entire guide to creating a C# COM component. Your component will now be immortalised as one of the wonders of the universe and will be visible from space*.

* Assuming your spaceship has a link to a Windows PC with your component installed on it.


Ian said...

Dude, This guide helped me through creating a COM-visible (immortal) component!

I have never worked with such ancient technology, not directly at least.

Thanks for this!

Jacob Christ said...

How do you register dll on a machine that does not have VS installed?

Benjamin said...

Hey Jacob,

use regasm.exe which comes with the dotNet framework

C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe "test.dll" /codebase /regfile


Jacob Christ said...

Thanks Benjarmin,

We have since figured that out, thanks for answering. I do have another question. Do you have to use the regasm.exe from the version of .net your dll was created in, or can regasm from any .net version work?