• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1452
  • Last Modified:

Exposing VB.NET assembly to VB6 using COM interop

Dear experts,

This is going to be a long story and I hope you can help me.

I've been busy now for 3 days to get our broken components to work again. We have made .NET COM components and succesfully called them in old VB6 applications. The components were made in Visual Studio 2005 w/ framework 2.0. Recently we've upgraded to Visual Studio 2008 and framework 3.5 and we discovered our applications were broken. We quickly found out that our .NET components did not work anymore. We got runtime errors saying "automation error" (helps alot huh).

I have eventually stripped down a .NET COM component to it's bare essentials just to get it to work in VB6. I have included the code with this thread just to show how simple my example is. In the IDE I have gotten these components to work. I can see in the objectbrowser the right object with the right method. Just when I run the executable I get the error of which I have included a screenshot in the attachments.

 I have included 2 versions of the COM component event. The first one "TestTemplate" (you can regonize this code by " TestTemplateClass" is an assembly to test the COM template provided with Visual Studio (VB.NET). As you experts know it is simple a matter of building the assembly and referencing it in your VB6 project, but alas... So I began to dig a lot deeper and you can see that result in the code "TestUtility". For the " TestUtility"  (recoginze it by " TestUtilityClass") I've done alot manually in the VS2008 command prompt, so I' ll list below what I've done. I have:
- Decorated all properties/interfaces/classes/methods with the appropiate attrributes (as the good practice guide lines from the MSDN prescribe) which you can see in the code samples
- vbc testutility.vb (to compile a dll obviously)
- tlbexp  (to make a type library)
- checked "register for COM interop" in the project properties
- regasm.exe (former steps didnt work so I tried this utility which is nonsense ofcourse because Visual Studio uses this utility too)
- I made a key pair with sn.exe to give my assembly a strong name
- Then called gacutil.exe to install my assembly in the GAC
- Because this didn't work I pasted the .dll and the .tlb in the VB6 project's directory
- Because this gave the same problems I copy/pasted the files in the same directory as where VB6.exe is located

Uhm... these are the most sane steps I can remember from the past three days. I've even used a log tool called fuslogvw.exe to log the behaviour of the com component in the vb6 application. This tool is only for when the application runs in the IDE so not very usefull for my problem. But I have included the log files in the attachment just to make sure. It is also worth noting that the .NET COM component and the VB6 application are on the same machine (which is my development machine... running Win XP and framework 3.5).
Again... I couldn't have made these assemblies simpler!
---------------------------------------------------Test Template------------------------------------------------
<ComClass(TestTemplateClass.ClassId, TestTemplateClass.InterfaceId, TestTemplateClass.EventsId)> _
Public Class TestTemplateClass
#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "6a22b94d-74e7-4bb7-ad90-2398faa72ef5"
    Public Const InterfaceId As String = "c78aed76-d3d3-4af7-bd5f-d7e8775669d1"
    Public Const EventsId As String = "f2fd0f05-acbe-4e4d-a5be-e19a0d259bcf"
#End Region
    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
    End Sub
    Public Function SayHello() As String
        Return "Hello!"
    End Function
End Class
Imports System
Imports System.Text
Imports Microsoft.Win32
Imports System.Runtime.InteropServices
<ComVisible(True)> _
<Guid("726F46F3-8A54-4c73-8545-D88D747AFF41")> _
<InterfaceType(ComInterfaceType.InterfaceIsDual)> _
Public Interface _TestUtilityClass
    <ComVisible(True)> _
    <DispId(&H1000001)> _
    Function SayHello() As String
End Interface
<ComVisible(True)> _
<Guid("62CD5DE0-170D-4cce-ADCF-21F676E8E019")> _
<ProgId("TestUtility.TestUtilityClass")> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class TestUtilityClass
    Implements _TestUtilityClass
    Public Sub New()
    End Sub
    Public Function SayHello() As <MarshalAs(UnmanagedType.LPWStr)> _
        String Implements _TestUtilityClass.SayHello
        Return "Hello!"
    End Function
End Class
---------------------------------------VB6 client code----------------------------------------------------------
Private Sub cmdOK_Click()
   Dim o As TestTemplateClass
   Set o = New TestTemplateClass
   MsgBox o.SayHello
End Sub

Open in new window

  • 5
  • 3
  • 2
1 Solution
Bob LearnedCommented:
Have you tried determining the dependency that it is looking for, with something like DependencyWalker?
LabelsoftAuthor Commented:
Yes. Unfortunatly VB6's dependency walker does not show dynamic components.

I have to add something to my story by the way. This morning I've succeeded in running the application by packiging and deploying the vb6 application and then copy/pasting the .dll in the same directory as where the app was installed. So I copied testtemplate.dll into c:\program files\testsuitevb6 because that is were testsuitevb6.exe was located. It works that way.

But I really need to know why it only works that way, because we have remote client comps which need updates aswell. So this is not a very practical situation.

Thnx for answering, keep it up.
Bob LearnedCommented:
On  the surface, it sounds like a bug with the way that the .NET assembly is registered as a COM component.  I see that you have an interface defined, and you tried REGASM to register, and yet you are still having that problem.   While I have 3.5, I have not used it with production, which is the only thing that has a COM component.

I wonder if this would be useful:

.NET assembly dependency analyser
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

You know, I've noticed a little bugginess working with COM like that before.  

What you might try doing is, (first copy your code),  delete the TestTemplateClass.  Then, Add A New Item... | select "Com Class".  Name it TestTemplateClass, then insert your code back into it.  

Here's an example that you can build and test:

For your reference, here's 2 articles that I've written about working with COM Interop:

Sorry...  Hit the submit button before I was ready...  Here's the links:



Hope that helps.

LabelsoftAuthor Commented:
I' ll give DependancyAnalyser a shot. I' ll let you know if it was usefull.

But I first tried VBRock's zip file. The enigma is getting bigger I'm afraid. Your project doesn't work. It says exactly the same as when I add a COM Class.

So... when I thought the answer was making a COM Class and building it, apparantly it's not. Apparantly I have done something to my TestTemplateClass (well... the .dll or the tlb file) to make it work. And stupidly enough I don't know which action made it work. I even tried building your project on my collegea's comp (same configuration) and then calling it via the vb6 app. Same error.

I'm going to read you articles now. I hope there's an action in there that makes your project work at my comp. Then I' ll know the trick. As for now... the saga continues unfortunatly.

So conclusion: Simply adding a COM Class in VS2008, building it, referencing it in VB6 app doesn't work for me guys. I need to do something extra. I need to find out what that is.

To be continued...
LabelsoftAuthor Commented:

Ok, I followed your first article... no go! Still a stupid automation error like I always got, reminding me of my conclusion that simply creating a COM Class and building it is not enough for my comp configuration apparantly.

BUT... after that I immediatly followed your 2nd article about the setup project anyway (despite the fact it didn't work yet). I used the setup project to install the COM and... voila! Suddenly it worked in my VB6 app.

Why do you think it works now? What does that setup project do extra? ' Cause I mean... you guys are right ofcourse... it SHOULD just work simply creating a COM Class (or going hardcore with your own interface and manually use regasm.exe).

What does that setup project do that I didn't?
Labelsoft - I honesty don't know exactly what Setup does when it installs a library and registers it.  All I know is it works every time.  I've had problems getting libraries registered with other methods, but never with a Setup project.

Also, on my computer I can create a COM library in VS, and build it, then go right to VB6 and use it without registering it or using a Setup project.  I'm not sure what's going on with your computer, but something is definitely different.

LabelsoftAuthor Commented:
Well, you know... You should get the points for writing those articles. So there you go... Case closed.

One more thing though. I've also noticed a difference between locally installing the dll (on your C: for instance) or trying to access them on a shared network directory. Me and two other collegeau's with similar config's (Windows XP, SP3, VS 2008, framework 3.5) all experienced something VERY strange. We'd put the library on our C: and use the checkbox ' register for COM' and then build. No go. The next day we did exactly the same and suddenly it worked. As though rebooting the comp helped. Our collegea with Windows 2003 (the rest the same) experienced no problem whatsoever. It worked immediatly on his comp by putting the stuff on his C: drive. He also couldn't get it to work from the network drive though, so that problem is consistent.

Ok, I'm moving on guys. Got more stuff to do then wonder about buggy COM registration. ;)

Thnx so far!
LabelsoftAuthor Commented:
Easy to understand articles. Made the COM assemblies work in VB6 eventually, as promised. But alas missed the in-depth knowledge about entries in the registry, the building of the type library, etc... to completly fathom the mystery of the buggy COM registration. But my guess is even Microsoft couldn't answer this better.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

  • 5
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now