Exact steps for registration-free COM interop in .NET (invoke copied COM dll without regsvr32)
Asked Answered
W

2

9

I want to add a registration-free COM reference to my .NET app. Registration-free means users can run the app without registering the COM component to their system.

I found a number of articles on this topic (e.g. MSDN, this S/O question, etc.) but none contains concrete steps. Here's what I have tried and did not work:

  1. Generate manifest for the COM dll (say foo.dll) using mt.exe as described in this answer.
  2. Add foo.dll and foo.dll.manifest to my app as "Build Action" = "Content" and "Copy to Output Directory" = "Copy Always".
  3. Add reference to interop.foo.dll that came with foo.dll.
  4. Add app manifest file with this section:

    <dependency>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="foo" />
      </dependentAssembly>
    </dependency>
    
  5. Build and run.

There's an error saying application configuration is not correct. Tried different values in <assemblyIdentity> without luck.

Could someone share experience? Thanks.

Watkins answered 1/6, 2012 at 22:59 Comment(0)
W
6

Hans's answer has the right information, but I wasn't clear what to do when I first read it. After trying many different things I finally got it working and it's very simple:

  1. Register the COM class on the developer machine.
  2. In the app project, add the COM reference.
  3. In reference properties, set these:
    • Isolated = True
    • Copy Local = True
    • Embed Interop Types = False (Hans pointed out in the comments that this is unnecessary but I haven't verified)

By following these steps, the interop.foo.dll and app manifest are automatically generated. This allows users to use the COM component without registration.

On the opposite, if you don't register the COM on the dev machine, you can still develop and build the app by adding reference to interop.foo.dll (which can be generated on a machine with the COM class registered and then copied around), but the build result can only run on machines with the COM component registered. There might be a solution around this but requires deeper knowledge of how MSBuild work with COM references, which I did not spend time investigating.

So in short, the key to runtime registration-free COM is to register the COM class on the dev machine.

Watkins answered 2/6, 2012 at 5:10 Comment(5)
Didn't you just say you want to do it without registering?Dubai
@Dubai I want the users to use the app without COM registration. The solution requires registration on the dev machine which is acceptable.Watkins
Wow! I wish i had found this answer years ago. All of the other guides I had been following required so much more manual effort!Hypogeum
Recommending Embed Interop Types = False is not good advice, embedding has no down-sides and plays no role whatsoever in usage of the manifest. One less file to deploy is always better. The secret sauce is Isolated = True, that's all.Underset
@HansPassant, I believe you that embed interop types should be true. What's interesting is that it only works for me if I set it to false. (When it's set to true I get the "Interop.Blah.dll cannot be specified for both /ink and /reference compiler options) My gut is there's something weird that vs2013 is doing when it calls CSC.exeMaffick
U
3

Your manifest is not correct. It should contain the <file> element instead of the <dependentAssembly> element. With <comClass> elements that declare the creatable co-classes.

Generating the manifest is a built-in feature in the VS build system. To make it work, the COM component needs to be installed correctly on your dev machine. Do not try a reg-free COM manifest unless you can make it work without one on your machine, you'll fight two problems instead of one. So for starters make sure that the server is properly installed, using the vendor's installer or deployment instructions. And make sure that a test program that creates an object and call a method operates correctly.

Exercising this is useful, with a known-good COM server that's available on any machine. Create a new project from the Console Application project template. Project + Add Reference, Browse tab, select c:\windows\system32\shell32.dll. Select the added Shell32 reference and change its Isolated property to True. Build + Rebuild.

Look in the bin\Debug build directory of your project and open the app.exe.manifest file with Notepad. Observe the file and comClass elements, that's what you'll need in yours as well. If this doesn't help then turn to the owner of the COM server, he should be able to provide you with the manifest you need.

Underset answered 1/6, 2012 at 23:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.