10
votes

I wrote a .net assembly using c# to perform functions that will be used by both managed and unmanaged code. I have a VB6 project that now needs to use the assembly via COM.

I created my .net assembly, made sure that ComVisible is set to true and that it is registered for COM interop via project properties.

public class MyClass

    [ComVisible(true)]
    public string GetResponse()
    {
        return "Testing Response"
    }

}

I build the assembly and copied the file into a folder. TestInterop.dll

I then run a batch file to register the assembly tool to register the object for COM.

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319\
regasm "c:\Program Files\TestApp\TestInterop.dll" /tlb:TestInterop.tlb

I open a new VB6 application and reference TestInterop.dll

In VB6 I write the following code and it compiles.

Dim obj as TestInterop.MyClass
Set obj = new TestInterop.MyClass

Dim strTest as string

strTest = obj.GetRespose()

When I run the program it errors on the obj.GetResponse() line.

Run-time error' -2147024894 (80070002'):
Automation error
The system cannot find the file specified

Also, the intellesense does not work on obj. I had to type the GetResponse method. Is this normal?

Does anyone have any clue what could be wrong or what steps I missed. Thanks!

5

5 Answers

13
votes

You'll want to put your .NET assembly in the GAC or else run RegAsm with the /codebase command line switch (it will complain, but this will at least work). No intellisense is normal, unfortunately.

4
votes

Last time I saw that I forgot to hard-code the GUIDs. So every time I recompiled VB would be unable to find my code. This is a template from VB.NET. (Don't use these GUIDs, make your own.)

<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
Public Class ComClass1

#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 = "eaf83044-f0a7-417b-b333-e45aec398ca5"
    Public Const InterfaceId As String = "84e0fb8f-266d-40e6-9e8c-3d4eb37d3bf0"
    Public Const EventsId As String = "22ea2214-032f-4eb6-b2d4-c5dd213bab87"
#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

End Class
1
votes

I have noticed that you don't need to run the RegAsm manually, actually just set AssemblyInfo property ComVisible to true:

[assembly: ComVisible(true)]

You can also do this by going to Project properties -> Application -> Assembly Information -> Make Assembly COM Visible, and set the check box.

It is not required to register the assembly you are creating into the GAC in order to use it from VB6.

0
votes

I think, the tlb file is generated under the framework directory as against this directory (c:\Program Files\TestApp).

Could that be the problem here?

0
votes

I was having the -2147024894 error, or other errors no matter what I tried, until I ran the vb6 consumer code directly from exe. Something about the VB6 debugger that was preventing from allowing me to use the dll at runtime. I couldn't even instantiate the object. I could reference the tlb at design time, and had perfect intellisense support too. As soon as I launched the application outside of Visual Studio everything worked perfectly. Hope this helps someone.