Click here to Skip to main content
Click here to Skip to main content

Creating a COM DLL with VS 2005: Advanced Walkthrough

By , 7 Jul 2009
 

Introduction

This article demonstrates how to create a COM DLL in Visual Studio 2005 the manual way.  It also demonstrates how to install it into the GAC with gacutil.exe, and how to register the library using the Assembly Registration Tool (regasm.exe).

To learn how to create a COM DLL the easy way, see my article "Creating a COM DLL with VS 2005:  A Walkthrough"

To learn how to register a COM DLL the easy way, see my article "Registering COM DLL with VS 2005 Walk-Through

 

Background 

After almost a year from posting my super simple article "Creating a COM DLL with VS 2005: A Walkthrough", I was surprised to find quite a few ratings lower than a 5. I figured there are probably a lot of developers that want to know the answer to the question: "How can I do this the hard way?" Well, for those sadistic sophisticated inquiring minds, here you go…

Just as a note, I'm thinking about writing an article about "Creating a COM DLL with the Visual Basic Command-line Compiler", which will use Notepad and Vbc.exe, so if you're really hard-core you may look for that. 

 

Creating the COM DLL Project

*** Just as a note, please follow these instructions closely.
*** If your COM DLL doesn't work when you're done, then you may have missed something.
 

To begin with, let's create a new Visual Basic.NET Class Library

  • Open Visual Studio 2005
  • Click on the File menu | New | Project…
  • In the New Project window, select:
    • "Visual Basic" from the Project Type.   
    • "Class Library" for the Templates.
    • Enter "MyComDemo" for the Name.
    • Check "Create directory for solution".
    • Click the "OK" button when you are finished.
 
1_-_NewProjectMenu.jpg

 

Programming the Class

First of all, notice that when Visual Studio created the project, it automatically added a class named "Class1".  Let's start our programming by changing the name of "Class1" to something more meaningful, like "MyCalculator".

  • View the Solution Explorer (View menu | Solution Explorer)
  • Right-click on Class1.vb, and select Rename from the drop down menu.

2_-_ChangeClassName.jpg 

  • Change the  file name from "Class1.vb" to " MyCalculator.vb". (This will change both the name of the file and the name of the class at the same time.)
3_-_ChangeClassName.jpg 

Let's add a method to our class that we can later call from VB6:

5_-_DisplayMsgSub.jpg 

 

Making it COM Interoperable

Now that we have our class programmed, we're ready to make our class COM Interoperable.

The first thing we need to do is Import the System.Runtime.InteropServices namespace.  This is required to obtain necessary interop attributes. 

Add the following to the top of the class:

            Imports System.Runtime.InteropServices

 

Define the Interface

The next thing we need to do is define an interface for our class. This is necessary, because this is what a COM client uses to communicate with a COM object.

To define an interface for our class, we will add the <ClassInterface()> attribute to our class, which will automatically generate an interface for us. This will ensure that each public member of our class will be exposed to COM.

  • Although it is technically optional, adding this attribute to our class allows the COM caller to take advantage of early binding, which is more type safe than late biding, and results in better performance.
  • Each class in our project that we want to expose to COM needs to have this attribute added to it.
  • There are 3 options available for the ClassInterface() constructor, we will use AutoDual:
    • AutoDispatch:  Interface will only support late binding
    • AutoDual:  Interface will support early binding and late binding.
    • None:  Interface will not support early binding or late binding.  (This option can be used if you have created your own strongly-type interface)

Our class should now look like this:

6_-_Interface.jpg 

 

Add a GUID

After our Interface has been added, we will need to add a specific GUID, which is a 128 bit number that gets added to the registry, and is used to identify a COM type.  (GUID is a Globally Unique Identifier)

To generate a GUID:

  • Click on the Tools menu | Create GUID
  • Select the Registry Format Option
  • Click the "Copy" button to copy the new GUID to the Windows Clipboard.
  • Click the "Exit" button to close the window.

7_-_GUID.jpg 

 

Now that we have our GUID, let's add the Guid() attribute between the ClassInterface() attribute and our class declaration.  Then, paste in the GUID. * Be sure to remove the curly braces {}.

Your class should now look like this:

8_-_AddGUID.jpg 

 

Define a Strong Name 

All Com Interop assemblies should be Signed, and installed into the GAC (Global Assembly Cache).  This is not technically required, if the assembly is not installed into the GAC, then it needs to be copied into the same folder as the COM program that is using it.

To sign the assembly:

  • Click on the Project Menu | MyComDemo Properties…
  • Click on the Signing tab.
  • Check the "Sign the assembly" checkbox.
  • Select "New…" from the "Choose a strong name key file:" drop-down list.
  • Create a Strong Name Key window:
    • Create a file name (eg. "MyComDemoKey")
    • Enter and confirm the password (optional)
    • Press the OK button.
    • Save and Close the Properties.

9_-_Signing.jpg 

 

Register for Com Interop 

Since we have the Properties window open, click on the Compile Tab, then check "Register for COM interop" at the bottom of the window.

10_-_RegisterForComInterop.jpg 

Finally, Save and close the Properties window.

 

Register our COM Interop Library 

Now that we have everything setup, change the solution configuration from Debug to Release, then save and compile the project.

Next, open the Visual Studio Command Prompt:

  • From the XP Start Menu, navigate to the Microsoft Visual Studio menu | Visual Studio Tools | Visual Studio 2005 Command Prompt.
  • Navigate to the directory where our compiled .dll is (bin\Release folder).

GAC: Installing our library into the Global Assembly Cache using the "gacutil.exe" utility makes our .dll globally available to all .Net assemblies, and prevents them from being copied into the application directory of the referencing assembly.

  • We must have Defined a Strong Name for our assembly before we can register it into the GAC (see Define A Strong Name above).
  • From the command prompt, type the following, then press enter: 

            gacutil –i MyComDll.dll 

11_-_GacInstall.jpg  

Registry: Registering our library into the Windows Registry using the "Regasm.exe" utility makes our COM type library .tlb (.dll) globally available to all VB6 assemblies.

  • From the command prompt, type the following, then press enter:

            regasm MyComDll.dll /tlb:MyComDll.tlb

12_-_RegAsm.jpg 

  • Our COM Type library (.tlb) has now been created, and is ready for use with VB6.

Note: "TlbExp.exe" is another utility that can be used to generate a COM type library from a .NET assembly, however it does not register it with the Windows Registry.

 

Using our new COM DLL in VB6 

We now have a functioning COM DLL ready to be used in VB6.  Let's go into VB6 and see how to use it.

Create a new VB6 Project:

  • Start VB6.
  • When the "New Project" window opens, select "Standard EXE".
  • Click the "Open" button
  • Add a button to the form, and double-click it to create the Click() event, and open the code window.

Add a reference to our new COM DLL:

  • Click the Project menu | References…
  • In the "Available References:" listbox, scroll down until you find our new library "MyComDemo", and then check it.
  • Click the "OK" button to close the "References" window.

13_-_Vb6Ref.jpg 

 

Finally, in the Click() event of our Command Button, add the following code to utilize our new library:  

    Private Sub Command1_Click()

        Dim calc As New MyCalculator
        Dim result As Integer
    
        result = calc.Add(5, 5)
    
        MsgBox result
    
    End Sub

To test our new COM DLL:

  • Run the VB6 application (F8 or Debug menu | Step Into).
  • Click the button on the form.

Here's the result of our test:

14_-_Vb6Output.jpg

 

Cleanup

When you are finished working through this article, you may want to remove the library we created from the registry. Here's how:

  • Open the Visual Studio Command Prompt.
  • Navigate to the directory where our compiled .dll is (bin\Release folder)
  • From the command prompt, type the following, then press enter:

            gacutil –u MyComDll.dll

15_-_Unregister.jpg

 

Conclusion

As you can see, it's quite a bit more work to create a COM DLL the manual way, including installing it into the GAC and registering it into the registry.

One thing to keep in mind is that if you try to install your COM DLL into the GAC, and register it in the registry on a computer other than your own development PC, you may find that the gacutil and regasm are not installed. If that is the case, you will need to install the .NET Framework Tools. Here is a link that has more information about them:

.NET Framework Tools.

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

VB Rocks
Software Developer DataPrint, LLC
United States United States
Member

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralThanks!!memberHernan.NET15 Sep '11 - 8:53 
thanks you, just in the moment that i need it
 
Hernan Maldonado
GeneralExcellent articlemembermr20011 Nov '10 - 7:45 
Hello,
 
It's a very useful and detailed article and I gave it a 5 rating.
However, I would suggest to specify that for redistribution purposes (i.e. installing the solution on another workstation) the following code can be used in order to register the component (includes codebase option):
 
regasm.exe myDLL.dll /tlb: myTLB.tlb /codebase
 

Regards,
M. R.
GeneralMy vote of 5membermr20011 Nov '10 - 7:40 
It's a very detailed article
GeneralCOM Rules!memberVitaly Tomilov3 May '10 - 8:52 
My vote is 5, and the reasons are:
 
1. The article does give a good start-up for someone who just approached the COM territory;
2. As an expert in COM with over 15 years of of writing it, i like seeing new articles appearing on this subject, even if they reiterate the old stuff. It is important that developers get familiar with COM, because COM is still at the core of any Windows OS, including, but not limited by Windows 7.
3. I want to support such articles to counter-vote stupid rants that come from .NET developers who pronounce COM dead and laugh at it. I laugh back at them, saying i've been hearing this since 1999, when Microsoft (what a joke) declared COM obsolete. It was one of those Bill Gates great ideas right after he announced Internet being obsolete Smile | :) )) Bill Gates is now obsolete/retired, while COM continues to prosper for many years to come.
 
If someone is interested in learning how to write professional COM servers usable from .NET or elsewhere, welcome to http://www.prosyslib.org
Professional System Library on www.prosyslib.org

GeneralHallucinantmemberCristian Amarie10 Jul '09 - 7:03 
To write COM dlls in .NET, and then to use in VB6 (??).
That's fantastic. And the extrasupermegaunnecessary layer
Net -> interop -> com -> interop -> net.
just kills me.
Perhaps an integration with JVM using a some sort of Py_CreateComObjectUsingInteropOnNetToRunOnJavaVMForPython would be an even better one.
 
Write one in C. I think the equivalent have some 7-8 Kb size with optimizations, and works at warp 8 comparing to such monstrosities.
Perhaps with Jeff Glatt samples and Matt Pietrek LIBCTINY we can got an equivalent COM server in 4 Kb.
If someone remembers LIBCTINY, of course.
 
THIS[^] is a COM article.
 
Nuclear launch detected

GeneralRe: HallucinantmemberMike Klimentiev14 Jul '09 - 8:21 
Cristian Amarie wrote:
Net -> interop -> com -> interop -> net.

 
Hate to start a flame but you are wrong. There is no .NET part in VB6. So it probably should read
 
Net -> interop -> com -> VB6
 
So while this article is not so useful for an experienced developer it might help some confused college student to get through his assignment. Still, it's probably better for that college student to go trade software stocks then go into software engineering. Unsure | :~
 
Or it can be used instead of VS Help that became pretty un-helpful in recent years.
 
In general I agree with you - entropy is definitely rising. But, hey, I heared it in 1991 when asembly language people were shrugging and asking "What's the reason to use TurboC if you can do *everything* in MASM faster, better and cooler?" Where is MASM now? I'd say that VB is slipping away too as it is not differnet from C# any more - way too confusing for Excel programmer.
 
end-of-flame
 
What was my point? I probably just need some coffee. Laugh | :laugh:
 
MK

GeneralRe: HallucinantmemberCristian Amarie15 Jul '09 - 18:46 
True for the VB6 part. I meant when are used from .NET.
 
College students having COM homeworks? Hmm.
Anyway, I don't know anyone who learned COM by at least using ATL. Finally, they come back to bare C++ (you *must* know how to implement at least DllRegisterServer, IClassFactory and IUnknown, right?). And even more finally, C. After all, 70% of Office is written in C AFAIK. Or more.
 
About MASM... I quote Peter Viscarola from memory.
He said - back "then" ... - something like:
"Show me a compiler that generates better assembly code than I do.
But today, there are compilers that generates a hell of a lot better code than I did. And I was really good."
 
Thing is, the C/C++ compilers now are mature and generates indeed very good asm code, so we can focus on libraries, logic and complexity of products instead of complexity of small functions.
 
Sadly, is not the case with .NET. Yet.
 
Nuclear launch detected

GeneralRe: HallucinantmemberVitaly Tomilov3 May '10 - 8:44 
Apparently you didn't work as long in the industry, because maintenance of existing software is one of the most important tasks that's being solved by developers. You come to a company that has plenty of software written in C++ and VB6, and they want you to start working on expanding it. And you are a .NET developer. So what you do, you write new modules and elements in .NET, and then expose them via COM so they can be used/called from within the old programs written in C++ and VB6. This is how it is done everywhere. Rewriting from scratch huge functional software just because it was written in an old development environment is not justifiable, and often not allowed by the client/customer.
 
Wink | ;)
Professional System Library on www.prosyslib.org

GeneralRe: HallucinantmemberCristian Amarie7 May '11 - 8:47 
15 years. Does it counts?
 
Nuclear launch detected

General[My vote of 1] Nothing newmemberMd. Marufuzzaman7 Jul '09 - 22:23 
Hi,
Sorry it's Poor Frown | :(
you can use the following
RegAsm myDll.dll /tlb:myDll.tlb /codebase
 
Thanks
 
Md. Marufuzzaman

GeneralRe: [My vote of 1] Nothing newmemberVB Rocks8 Jul '09 - 6:43 
What do you mean "it's poor"? My article is about creating a COM Interop DLL manually (not using the COM Interop template). It's not about how to register it, although I've included that in the demo.
 
I've seen a lot of people confused about this topic, so I know it's right on target. I've put a lot of work into it to make it clear, concise, and easy to follow, with solid documentation and lots of pictures.
 
Are you sure that a "1" is a fair grade for this article?
GeneralRe: [My vote of 1] Nothing newmemberVMykyt8 Jul '09 - 21:02 
<sarcasm>
of course this article worse than this one
http://www.codeproject.com/KB/cs/QuickEmailSend.aspx
<\sarcasm>
GeneralRe: [My vote of 1] Nothing newmemberjpaulino9 Jul '09 - 2:32 
I've voted on "5".
 
It's a great article and very well written.
 
Nice job VBRocks!
 
Jorge Paulino
VB.NET, ASP.NET, VBA, SQL
http://vbtuga.blogspot.com/

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 7 Jul 2009
Article Copyright 2009 by VB Rocks
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid