none
Reg Free COM Interop works with OCX but not with DLL RRS feed

  • Question

  • Good afternoon,

    I'm having trouble turning a .NET EXE that invokes a VB6 COM DLL that invokes a .NET DLL into a side by side application.  I've created a COM Visible .NET DLL in .NET (called COMVisibleDotNetDLL.dll):

    <ComClass(TestClass.ClassId, TestClass.InterfaceId, TestClass.EventsId)> _
    Public Class TestClass
    #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 = "e8b39720-c4a5-466e-b58d-6906026b6a1d"
        Public Const InterfaceId As String = "b3c49fd4-5adb-4d71-b5a0-e9d22d8b4b8c"
        Public Const EventsId As String = "f2b6e8a2-3344-4968-86c7-4cdcf07ab81d"
    #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 Sub HelloWorld()
            MsgBox("This is COMVisibleDotNetDLL.TestClass.HelloWorld() saying ""Hello!""")
        End Sub
    End Class
    

    I've then created a VB6 COM DLL (called VB6DLLCallingDotNet.dll) that invokes this COM Visible .NET DLL:

    Public Sub CallDotNet()
        MsgBox "This is VB6DLLCallingDotNet"
        MsgBox "This is VB6DLLCallingDotNet about to create COMVisibleDotNetDLL"
        Dim obj
        Set obj = CreateObject("COMVisibleDotNetDLL.TestClass")
        MsgBox "This is VB6DLLCallingDotNet about to call COMVisibleDotNetDLL"
        Call obj.HelloWorld
        MsgBox "This is VB6DLLCallingDotNet exiting"
    End Sub
    

    I've then created a VB.NET EXE that calls the VB6 DLL:

        Private Sub btnInvokeCOM_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInvokeCOM.Click
            MsgBox("This is DotNetEXEWeakCallingVB6DLL about to create VB6DLLCallingDotNet.TestClass")
            Dim obj As Object = CreateObject("VB6DLLCallingDotNet.TestClass")
            MsgBox("This is DotNetEXEWeakCallingVB6DLL about to invoke VB6DLLCallingDotNet.TestClass.CallDotNet")
            obj.CallDotNet()
            MsgBox("This is DotNetEXEWeakCallingVB6DLL about to exit")
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
        End Sub
    

    This works when the VB6 DLL is registered and when the ComVisible VB.NET DLL is registered.

    However, I then create a manifest for the COM Visible VB.NET DLL using mt.exe:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <assemblyIdentity name="COMVisibleDotNetDLL" 
                        version="1.0.0.0" 
                        processorArchitecture="msil"/>
      <clrClass clsid="{e8b39720-c4a5-466e-b58d-6906026b6a1d}" 
                progid="COMVisibleDotNetDLL.TestClass" 
                threadingModel="Both" 
                name="COMVisibleDotNetDLL.TestClass" 
                runtimeVersion=""/>
      <file name="COMVisibleDotNetDLL.dll" hashalg="SHA1" />
    </assembly>
    

    I embedd this as a resource into the COM Visible VB.NET DLL.

    I then add an Isolated reference in the VB.NET EXE to the VB6 COM DLL and after building get the following manifest:

    <?xml version="1.0" encoding="utf-8"?>
    <assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" 
              manifestVersion="1.0" 
              xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" 
              xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" 
              xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" 
              xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" 
              xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" 
              xmlns="urn:schemas-microsoft-com:asm.v1" x
              mlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <assemblyIdentity name="DotNetEXEWeakCallingVB6DLL.exe" 
                        version="1.0.0.0" 
                        type="win32" />
      <file name="VB6DLLCallingDotNet.dll" asmv2:size="24576">
        <hash xmlns="urn:schemas-microsoft-com:asm.v2">
          <dsig:Transforms>
            <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
          </dsig:Transforms>
          <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <dsig:DigestValue>srbcaUgEpj7Pc+xshX9Qhpe21ww=</dsig:DigestValue>
        </hash>
        <typelib tlbid="{900af973-7fc1-4e57-bfb4-976ed5776d2a}" 
                 version="1.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />
        <comClass clsid="{f5e8162d-e35b-41c7-89df-db0fac2cc287}" 
                  threadingModel="Apartment" 
                  tlbid="{900af973-7fc1-4e57-bfb4-976ed5776d2a}" 
                  progid="VB6DLLCallingDotNet.TestClass" />
      </file>
    </assembly>
    

    I manually add in the dependency to the VB.NET COM Visible DLL:

    <?xml version="1.0" encoding="utf-8"?>
    <assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" 
              manifestVersion="1.0" 
              xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" 
              xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" 
              xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" 
              xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" 
              xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" 
              xmlns="urn:schemas-microsoft-com:asm.v1" x
              mlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <assemblyIdentity name="DotNetEXEWeakCallingVB6DLL.exe" 
                        version="1.0.0.0" 
                        type="win32" />
      <file name="VB6DLLCallingDotNet.dll" asmv2:size="24576">
        <hash xmlns="urn:schemas-microsoft-com:asm.v2">
          <dsig:Transforms>
            <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
          </dsig:Transforms>
          <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <dsig:DigestValue>srbcaUgEpj7Pc+xshX9Qhpe21ww=</dsig:DigestValue>
        </hash>
        <typelib tlbid="{900af973-7fc1-4e57-bfb4-976ed5776d2a}" 
                 version="1.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />
        <comClass clsid="{f5e8162d-e35b-41c7-89df-db0fac2cc287}" 
                  threadingModel="Apartment" 
                  tlbid="{900af973-7fc1-4e57-bfb4-976ed5776d2a}" 
                  progid="VB6DLLCallingDotNet.TestClass" />
      </file>
      <dependency>
        <dependentAssembly>
          <assemblyIdentity name="COMVisibleDotNetDLL"
                        version="1.0.0.0"
                        processorArchitecture="msil"/>
        </dependentAssembly>
      </dependency>
    </assembly>
    

    When I run this up on another machine, the VB.NET EXE invokes the VB6 COM DLL fine, but the VB6 COM DLL raises an

    exception trying to instantiate the VB.NET COM Visible DLL:

    System.IO.FileNotFoundException: Automation error
    The system cannot find the file specified.
       at Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack, Boolean IgnoreReturn)
       at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn)

    I can do this same thing except instead of a VB6 DLL in between two .NET DLLs, I have a VB6 OCX.  Everything works fine.  If I have both the OCX and the VB6 DLL in the .NET EXE, then the VB6 DLL code only works if the OCX code has run first (and loaded the VB.NET COM Visible DLL I assume).

    Any help would be appreciated,
    Thanks!
    Jason.

    Thursday, February 25, 2010 2:34 AM

All replies

  • Have you been able to find a solution to this problem ? Or the reason for it ?

    I'm having same issue with C++ DLLs in between C# .NET assemblies.

    Sunday, April 11, 2010 6:53 PM
  • Hi there, sorry to hijack this thread but thought I would see if anyone could help.

    I have developed a vb.NET DLL which needs to be called from our main business system at work which is a vb6 Executible. Hence I have made my .Net dll com visible.

    My .Net dll in turn references a VB6 DLL containing a substantial amount of logic that is also used in the main business system as well.

    So I am going VB6 EXE (1)  > VB.NET COM DLL (2)  > VB6 COM DLL (3). When I added the reference to the vb6 dll (3) visual studio automatically put a wrapper around it and called it interop.vb6dll.dll. my vb.NET dll (2) all builds fine.

    I wrote a vb6 test platform for my .net dll and added a reference to the Vb.NET (2)'s TLB file and then extantiated it using early binding. (have tried it with late binding also and this works too) on the development machine.

    The problem lies when I try and deploy this. Have tried every thing under the sun over the last 2-3 weeks and still cannot get it to run on 'normal' client machines.

    1st tried regasm of the DLL with /TLB option but for some reason regasm will not even run on client machine (no error - just that it has 'stopped working').

    2nd tried reg free com, but to no avail either.

    just wondering if anyone has had any experience of going from vb6 -> vb.net and back to vb6? surely I cannot be the first person!

    On verge of pulling my hair out - have spent 9 months on this project and if I cant get it to run on client machines I'm in for a telling off!

    any help hugely appreciated!

    cheers,

    Steve

    Wednesday, May 19, 2010 3:40 PM
  • Fixed this today - the client machines were built with a corrupt/dodgy .net framework - this explained why nothing .net would work (I went back to apsolute basics and just tried a .Net exe with a single form with a label on it!) - this didnt work either so we figured something was up.

    We were getting "your application has stopped working" system error (wouldnt even fire up my exe to show error caught in the try/catch block). This was telling me it was a 'CLR20r3" error - runtime.

    On reinstalling .net framework it now works - great success!

    ..now we have to work out how to do this on 300 client machines... ohh what fun.

    I hope this may be of some help to someone reading this.

    Best,

    Steve

    Thursday, May 20, 2010 2:37 PM