6

I have ActiveX VB6 DLL (have no access to its sources), and want to call method 'GetUnitInfo'

I use to import it like:

[DllImport(@"C:\Users\R\Documents\lab.dll")]
public static extern long GetUnitInfo(String strRequest, String strInfo, String strName);

But I get an exception:

Unable to find an entry point named 'GetUnitInfo' in DLL

Also I have tryied to load it:

Assembly myAssembly ;
myAssembly = Assembly.LoadFile("C:\\Users\\R\\Documents\\lab.dll");

but getting an exception

The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)

I have tryied to clean solution, to turn off manifest in project options, to create new manifest file, but it did not helped me...

Little Fox
  • 1,212
  • 13
  • 39
  • 7
    Is this a **VB.NET** or **VB6** DLL? For VB.NET DLLs you just have to right-click your project in the `Solution Explorer`, press `Add Reference...` and locate the DLL. `DllImport` is only used when you want to call functions in _**native**_ DLLs (such as DLLs compiled with C, C++ or VB6, etc.) – Visual Vincent Sep 27 '18 at 15:39
  • 2
    If it were a VB.Net dll, he wouldn't get the error about the missing manifest. – Joel Coehoorn Sep 27 '18 at 15:42
  • 2
    And if it was a VB6 dll, there would be no entry point because VB6 produced ActiveX dlls. (It was possible to produce native dlls with exported functions in VB6, but that required writing funky code and intercepting calls to the linker, `link.exe`.) – GSerg Sep 27 '18 at 15:46
  • @VisualVincent looks like it is VB6 dll, because I get an error after adding it, at "using lab;" (can't find namespace) – Little Fox Sep 27 '18 at 15:47
  • 1
    Unfortunately I've never used VB6 DLLs in .NET so there's not much more I can suggest... What program did you decompile it in? If it's a .NET DLL it should be decompilable by [ILSpy](https://github.com/icsharpcode/ILSpy/releases/tag/v3.2.0). – Visual Vincent Sep 27 '18 at 16:13
  • @GSerg : Interesting point, I wasn't aware of that! (My VB6 days were way back, when I barely knew how to code ;) – Visual Vincent Sep 27 '18 at 16:15
  • 1
    If it's a VB classic dll, then you should be able to add it as a COM reference and use the built-in COM interop machinery to work with it. (The great thing about it originating in classic VB is that it will almost certainly not have done any of the interesting tricks that the built-in interop machinery doesn't know how to handle...) – Craig Sep 27 '18 at 18:02
  • Possible duplicate of [Best way to access COM objects from C#](https://stackoverflow.com/questions/635839/best-way-to-access-com-objects-from-c-sharp) – StayOnTarget Sep 28 '18 at 13:31

1 Answers1

8

Found solution, mb someone else will find useful, (this worked in my case):

  1. Create .Net wrapper of VB6 ActiveX dll

    1.1 Run CMD as Administrator

    1.2 Move to .NET SDK folder - cd C:\Program Files\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\ (in my case).

    1.3 Run - TlbImp.exe C:\path_to_old.dll /out: new.dll

  2. Register ActiveX dll

2.1 Run CMD as Administrator

2.2 Run - regsvr32.exe C:\path_to_old.dll

  1. Add Reference to converted dll ("new.dll") in c# project

I used to add "new.dll" reference before registering "old.dll", and was getting the following exception

Retrieving the COM class factory for component with CLSID {F2D4F4E5-EEA1-46FF-A83B-A270C92DAE4B} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))

Cleaning solution, removing reference and following steps 2,3 - helped

You may also find useful this articles

C-Sharp-and-activex-dll

Error adding reference to dll: Solution tlbimp.exe

zeocrash
  • 636
  • 2
  • 8
  • 31
Little Fox
  • 1,212
  • 13
  • 39
  • 1
    FYI tlbimp isn't converting to .NET per se, it's just creating an .NET interop wrapper which handles the fine details of moving between your .NET code and the COM code in the reference. When you make a call into the old dll, you will still ultimately be executing code in that dll. – Craig Sep 27 '18 at 19:03
  • It doesn't convert, it creates a wrapper. You can use the wrapper, or you can just use `dynamic` and `Activator.CreateInstance`. The only step that is required is registering the dll. – GSerg Sep 27 '18 at 19:04
  • @Craig, GSerg yes, I'm sorry, my bad. – Little Fox Sep 27 '18 at 19:38
  • 1
    Great answer! This is perfect for future duplicates! By the way you might want to mention that the VB6 DLL must be included (I think?) and registered on the target computer as well when deployed/installed. – Visual Vincent Sep 27 '18 at 21:39
  • 1
    A more integrated method of doing the same thing is described here: https://stackoverflow.com/a/635871/3195477 – StayOnTarget Sep 28 '18 at 13:32