Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to reference a COM DLL in a managed project by path rather than by GUID?

Tags:

.net

msbuild

com

I have a managed (asp.net, actually) project that references a COM DLL. Right now, the reference in the .csproj looks like this:

<COMReference Include="thenameinquestion">
  <Guid>{someguidhere}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>tlbimp</WrapperTool>
</COMReference>

This works, but it has the unfortunate consequence that the DLL needs to be registered on the build machine, which means (among other things) it's inconvenient to build multiple versions of the project that use different versions of the DLL on the same build machine.

MSDN shows the ResolveComReference task that looks like it does the right thing, but my google-search-fu hasn't been good enough to come up with an actual example of its usage. Is it possible to do what I want? Am I on the right track?

like image 638
Dan Davies Brackett Avatar asked Jul 09 '09 20:07

Dan Davies Brackett


2 Answers

When you reference a COM DLL, Visual Studio automatically generates an interop assembly for it. I find that taking manual control of this process is a great way to decouple the COM and .NET builds.

  1. Create your own interop assembly for the COM DLL using tlbimp.exe. See MSDN for the command line parameters.
  2. Reference your interop assembly in the .NET project instead of the COM DLL.

Once you do this, you no longer have to have the COM DLL registered on the machine when you build the .NET solution, only your interop assembly is required.

The interop assembly can sit in a folder unchanged forever until such time as (a) the COM DLL breaks binary compatibility, or (b) a COM interface change is made that the .NET code actually uses.

If you have different versions of the COM DLL which are all binary compatible, then compile the interop assembly against the earliest version containing the interfaces that the .NET code requires. You will then not have to update the interop assembly for different versions.

In addition, you don't need to include the COM DLL in your installer if you are in a position to assume that the COM DLL will already be installed on the target machine.

like image 193
Christian Hayter Avatar answered Nov 15 '22 21:11

Christian Hayter


As John Fisher pointed out already you are looking for Registration-Free COM Interop. There are plenty of questions already regarding this, look for the 'tag at hand' regfreecom and the closely related tag sxs too.

You'll easily see, however, that this can be a tricky arena, in particular:

  • There appears to be a confirmed bug affecting this on Windows XP, see here for details. A hotfix is available already though, which might be sufficient as long as you are targeting a controlled environment only, e.g. your build machine.
  • Since you are targeting ASP.NET you should be aware that in contrast to e.g. a desktop application this implies you are not in control of the hosting process, which may vary depending on the deployment platform. This means it won't be easy to supply the required application manifest to control the runtime binding and activation of your COM component within the host (see next point for a potential alternative).
  • ASP.NET 2.0 seems to complicate things even more by dropping side by side functionality for unmanaged components. I haven't found an official source for this but the author of Isolating ASP .Net 2.0 Applications seems to be in the know; he is offering a workaround at least, which looks complicated and potentially fragile though.

Summarizing this I'd like to stress that 'Registration-Free COM Interop' can be very helpful and ease many scenarios a lot. Still it may not make things easier or even be possible at all for your particular scenario and environment (hosted ASP.NET).

Good luck, please let us know whether you succeeded!

like image 34
Steffen Opel Avatar answered Nov 15 '22 22:11

Steffen Opel