Wednesday, 19 August 2009

Registration Free COM

From Windows XP SP2 Microsoft introduced a feature called RegFree COM, which allows you to call COM objects (yes some of us still use COM) without needing to register them first. The object in question must be in the same folder as the caller but this makes it much easier to install these objects and goes a little way to the xcopy distribution utopia. To use RegFree COM your caller and callee assemblies needs to have manifest files either externally or embedded - Manifest Files Reference. The assemblies can be written in any language that supports COM and you can call between languages, e.g. vb to vb, vb to .Net, .Net to vb.

The calling application needs a manifest file configured as follows, in this example the application is called MyApp.exe so the manifest is MyApp.exe.manifest:

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="MyApp" version="0.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="ComAssembly.dll" version="1.2.3.4" />
</dependentAssembly>
</dependency>
</assembly>

The COM assembly needs a manifest file configured as follows, in this example the assembly is called ComAssembly.dll so the manifest is ComAssembly.dll.manifest:

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="ComAssembly.dll" version="1.2.3.4" />
<file name="ComAssembly.dll">
<comClass clsid="{11111111-2222-3333-4444-555555555555}" threadingModel="Both" />
</file>
</assembly>

In MyApp.exe.manifest I have set the version to “0.0.0.0” this should really match the application version but “0.0.0.0” works. The dependentAssembly/assemblyIdentity  can be repeated for as many COM dependencies that you have.

The assemblyIdentity in the caller manifest must match exactly the one in the callee.

Getting this right can be quite difficult to debug, on XP the only clues to problems are written to the system eventlog with the source SideBySide. On Vista (and I assume Windows 7 and Windows Server 2008 although I haven’t tried it) you can use SxsTrace to help debug the problem. To start trace run “SxsTrace Trace -logfile:SxsTrace.etl” to convert the log file to something you can view run “SxsTrace Parse -logfile:SxsTrace.etl -outfile:SxsTrace.txt”.

The two manifest files presented here have been reduced to the minimum required to get the code to work, they are more settings that can be included see the Manifest Files Reference for more details.

See also:

4 comments:

Christopher Painter said...

I heard about this 5 years ago but dismissed it because of all the W2K systems I still had to support.

The other day this topic came up because some developer wanted to add 100+ COM DLL's to his install and I cringed at the risk and complexity.

I suggested COM Free Reg but it was shot down because the developer didn't want to take on the responsibility of generating the manifest files.

I then asked the developer if he really needed all 100 DLL's or only a handful. I was told that he didn't know but that the product needed to ship in a couple of days and he didn't have time to find out.

Oh the joy...

Neil Sleightholm said...

I am using this quite a bit now but nothing like 100 DLLs! I think the manifest files can be auto generated fairly easily as they don't need much meta data from the DLL. For .Net COM components I embed the manifest in the assembly as it makes it easier to manage.

Christopher Painter said...

Sadly these were third party runtime dll's from LEADTOOLs. If you look at their deployment instructions it's literally from the 1990's.

They don't give a prereq instaler, MSI or MSM. They just give you a ZIP file with the instructions to deploy them to System32 and use RegSvr32 to register them.

Pally Sandher said...

I'm so going to implement this for our next major release.
Being able to push some of the installation headaches over to the rest of the development team might make them more aware of the problems they cause.
If it saves me having to run the COM exposed DLL's through heat.exe everytime there's a version number change I'm all for it.