Solved

Exposing VB.NET assembly to VB6 using COM interop

Posted on 2009-05-11
10
1,406 Views
Last Modified: 2013-11-26
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()

        MyBase.New()

    End Sub

 

    Public Function SayHello() As String

        Return "Hello!"

    End Function

End Class

-------------------------------------------TestUtility-------------------------------------------------------------

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()

        MyBase.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

mscorlib--Version-2.0.0.0--Cultu.txt
TestTemplate--Version-1.0.0.0--C.txt
runtimeerror.bmp
0
Comment
Question by:Labelsoft
  • 5
  • 3
  • 2
10 Comments
 
LVL 96

Expert Comment

by:Bob Learned
Comment Utility
Have you tried determining the dependency that it is looking for, with something like DependencyWalker?
0
 
LVL 3

Author Comment

by:Labelsoft
Comment Utility
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.
0
 
LVL 96

Expert Comment

by:Bob Learned
Comment Utility
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
http://www.drewnoakes.com/code/dependancyanalyser/
0
 
LVL 27

Expert Comment

by:VBRocks
Comment Utility
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:
  https://filedb.experts-exchange.com/incoming/ee-stuff/7636-TestUtilityClass.zip

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



0
 
LVL 27

Accepted Solution

by:
VBRocks earned 250 total points
Comment Utility
Sorry...  Hit the submit button before I was ready...  Here's the links:

     http://www.codeproject.com/KB/COM/VS2005ComDllWalkThru.aspx

     http://www.codeproject.com/KB/COM/VS2005RegisteringComDLL.aspx


Hope that helps.

0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 3

Author Comment

by:Labelsoft
Comment Utility
@TheLearnedOne:
I' ll give DependancyAnalyser a shot. I' ll let you know if it was usefull.

@VBRocks:
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...
0
 
LVL 3

Author Comment

by:Labelsoft
Comment Utility
@VBRock:

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?
0
 
LVL 27

Expert Comment

by:VBRocks
Comment Utility
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.

0
 
LVL 3

Author Comment

by:Labelsoft
Comment Utility
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!
0
 
LVL 3

Author Closing Comment

by:Labelsoft
Comment Utility
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.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Normally the drop down box control found in the .Net framework tools is able to select just one data and value at a time, which is displayed on the text area.   But what if you want to have multiple values to be selected in the drop down box? As …
In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now