How do I expose a .netstandard2.0 library with COM for use in VB6?

后端 未结 3 1230
春和景丽
春和景丽 2020-12-11 06:16

I have a dotnet core library, a framework 4.7.2 library and a vb6 application.

I want to write a common library for them all to access and so choose .netstandard2.0<

3条回答
  •  温柔的废话
    2020-12-11 07:05

    Regarding the .NET standard, I may be wrong but I think this is not applicable here because the COM interop stuff are at a higher level than the one .NET standard is targeting; we can only talk about either .NET Core or .NET Framework for COM interop.

    If you want to generate a type library, you have few options.

    By far, the easiest method is just to use .NET Framework. The fact that you are wanting to create a type library negates the advantages of .NET Core already because several COM, especially the "Automation" features are Windows-only. Using framework will be fine at least until .NET Core 5 comes out.

    That said, if you have a business reason for using .NET Core but still need COM support, including the type library, then based on this GitHub comment, you should be able to compile your own IDL. Note that requires you to install C++ build tools because the MIDL compiler is not really a standalone thing that you can get without the rest of the C++ build tools.

    It is strongly suggested to have had read the documentation on how .NET Core handles COM activation.

    Assuming having the C++ build tools is not a barrier for you, the steps would be the following:

    1) Create a .idl file that defines all your COM interfaces in the IDL format. That requires some translation between the .NET interface and the COM interface. Here's a partial example of how you'd need to translate between your C# interface and COM interface as defined in IDL:

    [
      Guid(""),
      InterfaceType(ComInterfaceType.InterfaceIsDual)
    ]
    public interface IFoo 
    {
       string Bar { get; }
       string Baz(int Fizz);
    }
    

    Would be translated into IDL:

    [
      uuid(),
      version(1.0)
    ]
    library myFoo
    {
      [
        uuid(),
        object,
        dual
      ]
      interface IFoo : IDispatch {
        [propget] HRESULT Bar([out, retval] BSTR* retVal);
        HRESULT Baz([in] long Fizz, [out, retval] BSTR* retVal);
      }
    }
    

    Once you've defined the .idl file and it is an accurate representation, you can then use MIDL to compile the .idl file into a .tlb file. Usually something like midl foo.idl /tlb: foo.tlb. You should make use of the MIDL language reference to help you write the .idl file. As a quick way to get started, you could copy your C# interfaces to a .NET framework project, use tlbexp, then use oleview (available via Visual Studio Developer Command Prompt) or olewoo to view the resulting IDL file to get you started.

    The next step is to then create registry keys so that your CLSID can reference the type library. You will need to have your assembly's GUID handy and it must be used as the library's uuid in the .idl file as well.

    Using IFoo interface example, you would need to create the registry similar to below (using .reg format for easy sharing/comprehension and assuming per-user installation, rather than per-machine):

    Windows Registry Editor Version 5.00
    
    [HKEY_CURRENT_USER\Software\Classes\Interface\{}]
    @="IFoo"
    
    [HKEY_CURRENT_USER\Software\Classes\Interface\{}\ProxyStubClsid32]
    @="{00020424-0000-0000-C000-000000000046}"
    
    [HKEY_CURRENT_USER\Software\Classes\Interface\{}\TypeLib]
    @="{assembly gooey}"
    "Version"="1.0"
    

    You will also need to create the registry in the CLSID, Interface, TypeLib, and Record as needed. This article provides a good overview of all registry keys but keep in mind it's assuming .NET framework, not .NET Core, so not all keys are applicable, especially under the CLSID branch.

    Note that when you run the regsvr32, it will normally create the keys in the CLSID and Interface branches but you will need to add the TypeLib keys under the Interface's branch and also an entry to the TypeLib branch. You also will need to create the ProgId keys, too if you want to support CreateObject functionality.

    Initially, you can start with just a .reg file that you can manually update & maintain but if you have several objects, then it becomes desirable to automate this. This can be also managed via the DllRegisterServer call so that when you execute regsvr32, it will take care of registering the keys. On the other hand, you're now polluting your codebase with registration code. Some elect to use installers to do the registry keys write instead.

    I hope that helps you get started!

提交回复
热议问题