In one of the earlier posts I mentioned a problem with registration-free COM dependency setup up by Visual Studio as a part of build process. This post is about the tool that offers an alternate solution for the problems, and also gives more:
- standalone, independent from build, addition/removal registration-free COM links
- automation of registration-free COM links for native code builds
Unless one deals with
ACTCTX activation contexts programmatically, taking advantage of registration-free COM is essentially a setup of respective side-by-side manifests, either standalone or embedded into executable. The manifests override standard global COM object lookup procedure and point to COM servers directly, in some way similar to the way static links to exported DLL functions work.
To enable, registration-free COM reference COM client needs to prepare respective manifest file (declare an assembly) and list its COM dependencies. The COM dependency list is not just COM server files but rather their COM classes and type libraries. That is, when it comes to automation, the tool needs to go over the COM servers and extract respective identifiers, so that it could properly shape this information and include into manifest XML.
To deal with the challenge, I am using
ManifestComDependency tool (no better came to mind when it was created). The command line tool syntax is the following:
ManifestComDependency <path> [options] Options: * /i[:<assembly-name>] - updates <assemblyIdentity> element replacing it with automatically generated * /a[:tc] <dependency-path>[|LIBID[;X.Y]] - adds file <dependency-path> dependency, optionally without type library and COM classes reference * /r <dependency-path> - removes dependency from file <dependency-path> * /e <export-path> - exports manifest to file <export-path>
The tool opens a file
<path> for manifest modification. The file can be a binary file, such as
.dll, in which case the tool will be working with embedded manifest resource. Or, if the path extension is
.xml, then the file is treated as standalone XML manifest file. Both options are good for manifests associated with .NET builds as well, even though this surely does not need to be managed code development – native COM consumers are okay.
/i option updates
<assemblyIdentity> element in the manifest data because it is mandatory and in the same time it might so happen that it is missing or incomplete, which ends up in painful troubleshooting. The tool will name file name, architecture and version information from the binary resource information (product version; the
VERSIONINFO resource has to be present).
/a option adds a dependency, defined by either path or registered type library identifier the tool would use to resolve the path.
c modifiers exclude type library and COM server information respectively. The tool created a
file element for the dependency and populates it with COM servers discovered there. Type library is obtained using
LoadTypeLib API and COM servers are picked up by a trick with
RegOverridePredefKey and friends (e.g. see example in regsvr42 source or GraphStudioNext source – both are excellent sources of code snippets for the curious).
The task of COM server discovery assumes load of the library into process (
LoadLibrary API call), which assumes bitness match between the tool and the loaded module. This is where you need both
x64 builds of the tool: if wrong bitness is detected, the tool restarts its sister build passing respective command line arguments, just like
regsvr32 does with the only difference that
regsvr32 uses binaries in
syswow64 directories, and my tool looks for
-x64 suffixes and the files in the same directory.
/r option removes dependencies by name. It is safe to remove certain dependency before adding it back because addition does not check if dependency already exists.
/e option writes the current version of the manifest in external file, esp. for review and troubleshooting if the actual manifest is embedded.
The order of options is important because they are executed one by one in the order of appearance. Then the result is saved/re-embedded once all tasks are done.
Command line example of re-adding registration-free COM dependencies:
ManifestComDependency-x64.exe BatchExport-x64.exe /i /r Player.dll /r mp4demux.dll /a Player.dll /a mp4demux.dll
This can be set as post-build event in the project settings, or put into batch file or run on-demand.