How can C# use a legacy DLL simply without registr

2019-04-08 08:18发布

问题:

Situation
I run a build system that executes many builds for many project. To avoid one build impacting another we lock down the build user to only its workspace. Builds run as a non privileged users who only have write ability to the workspace.

Challenge
During our new build we need to use a legacy 3rdparty DLL that exposes its interface through COM. The dev team wants to register the build(regsrv32.exe) but our build security regime blocks this activity. If we relax the regime then the 3rdparty DLL will impact other builds and if I have two build which need two different versions I may have the wrong build compile against the wrong version (a very real possibility).

Question
Are there any other options besides registration to handle legacy DLLs which expose their interface via COM?

Thanks for the help

Peter

回答1:

There's a walkthrough on registration-free COM here:

http://msdn.microsoft.com/en-us/library/ms973913.aspx

And excruciating detail here: http://msdn.microsoft.com/en-us/library/aa376414 (the root of that document is actually here: http://msdn.microsoft.com/en-us/library/dd408052 )

Also, for building in general, you should be able to use Tlbimp or tlbexp to create a TLB file that you can use for building, assuming the point of registering is just to be able to compile successfully, and not to run specific tests.



回答2:

For my original answer to a similar question see: TFS Build server and COM references - does this work?

A good way to compile .NET code that references COM components without the COM components being registered on the build server is to use the COMFileReference reference item in your project/build files instead of COMReference. A COMFileReference item looks like this:

<ItemGroup>
  <COMFileReference Include="MyComLibrary.dll">
    <EmbedInteropTypes>True</EmbedInteropTypes>
  </COMFileReference>
</ItemGroup>

Since Visual Studio provides no designer support for COMFileReference, you must edit the project/build file by hand.

During a build, MSBuild extracts the type library information from the COM DLL and creates an interop assembly that can be either standalone or embedded in the calling .NET assembly.

Each COMFileReference item can also have a WrapperTool attribute but the default seemed to work for me just fine. The EmbedInteropTypes attribute is not documented as being applicable to COMFileReference, but it seems to work as intended.

See https://docs.microsoft.com/en-ca/visualstudio/msbuild/common-msbuild-project-items#comfilereference for a little more detail. This MSBuild item has been available since .NET 3.5.

It's a shame that no-one seems to know anything about this technique, which to me seems simpler than the alternatives. It's actually not surprising since I could only find just the one above reference to it on-line. I myself discovered this technique by digging into MSBuild's Microsoft.Common.targets file.



回答3:

Installation tools such as Installshield can extract the COM interfaces from the DLLs and add them to the registry. It can also use the self-registration process of the DLL (which I believe is what regsvr does), but this is not a Microsoft installer best practice.



回答4:

in .NET COM is normally done thru Interop in order to register .DLL in .NET they are called Assemblies and that can be done several ways.. by adding references via VS IDE at the project level, or writing code that Loads and unloads the assembly.. by .Config file that haas the reference to the assembly as well as the using of that reference within the project... GAC.

  • If you have access to the 3rd party .DLL's you can GAC them, and reference them in your project
  • you can add a using to your .cs file header as well as add the reference to the project by right clicking on reference --> add Reference ...
  • you can also do the above step as well as set the copy local = true in the properties for that .dll.. I hope that this gives you some ideas.. keep in mind that .NET assemblies are Managed code so there are several ways to Consume those 3rd party .DLL's using other methods within C# like LoadFromAssembly ect..


回答5:

Thanks for all the help.

We changed from early-binding to late-binding because we never really needed the DLL at compile time. This pushed the registration requirement from the build server to the integration test server (where we execute the installer which handles the registration). We try to keep the build system pristine and have easy-to-reset integration systems.

Thanks again Peter