View RSS Feed

Development Team Blog

Registration-Free COM [by Dan Levene]

Rating: 19 votes, 5.00 average.
Registration-Free COM

I was privileged to deliver a presentation on this topic at the recent Synergy 2011 Conference in Orlando. As a result of discussions that ensued from that presentation and the broad interest that seems to exist in this topic, I am also privileged to offer this guest blog.

First, indulge me while I provide some background on the technology from Microsoft that makes this possible and attractive; then, I'll show how it's done.

What is Registration-Free COM?

It is a method to deploy and use COM controls and automation objects without having to register them to Windows (via regsvr32.exe, commercial installers such as InstallShield or Wise, or custom installers).

It is really an informal reference to a little-known Microsoft specification of techniques formally named Isolated Applications and Side-by-side Assemblies. A set of topics that document the solution can be found on-line in the Microsoft Developer Network (MSDN) Windows Development Library. (For more information, follow the link: Isolated Applications and Side-by-side Assemblies.)

These techniques are available in all Windows operating systems from XP forward and are implemented through the use of application manifest files. You've probably noticed manifest files laying around next to Visual DataFlex compiled executables with the same name as the executable plus the added extension ".manifest", like order.exe.manifest for the Order Entry example program. Visual DataFlex has generated these files for at least the last 5 or 6 major revisions to meet the requirements of creating fully compliant Windows OS executables. If you've ever bothered to open one for examination you've probably noticed that it is really just an XML document with some modest information that describes the application. It turns out, there's a whole lot more that can go into the manifest to instruct Windows on the context in which the application should run. For instance, with applications running on Windows Vista, Windows 7 or Windows 2008 Server, the UAC security context requirement can be asserted in a <TRUSTINFO>member. So, for example, if an application needs to run with administrator privileges, adding a correctly-configured <TRUSTINFO>member will force these newer operating systems to prompt the user for permission to proceed and alternate credentials if the current user is not an administrator.

What I'm interested in discussing here is adding information that will allow the executable to get what it needs to run COM controls from the manifest rather than from the registry.

Why Registration-free COM?
  • To eliminate the need for administrator privileges to install COM controls. (Since no public, permission-protected registry entries or folders outside of the application's own installed location(s) are required, any user that has access to an application's installed folder should be able to run the application.)
  • To simplify installation process architecture.
  • To increase the portability of installed applications.
  • To eliminate conditional locating of COM control files by forcing the application to use a resource (in this case, COM controls) from a specified location (relative to the executable’s path) and from nowhere else.
    • If the manifest is incorrect, Windows fails the executable launch with a message to the end user that the application is not installed correctly.
    • If the resource is missing from the specified location, the app functionality that depends upon it will fail.
    • In other words, if installed correctly the app will work, if not, the app will fail positively—no in between mysterious behavior because a component was found in a directory unrelated to the intended installation or because permissions in some external location are not sufficient for the current user's execution context.
Highlights of the Microsoft's MSDN Documentation

As a bit of background, here are some brief statements I've gleaned from studying the MSDN on Isolated Applications and Side-by-side Assemblies. My goal isn't to provide a complete understanding of these topics but to at least let you know in a nutshell what each of these topics is generally about.


Isolated Applications
  • An application is isolated to the extent that everything an application executable needs to run is in the directory where the executable is found.
  • A totally isolated application can be deployed with a simple file system copy of the directory (xcopy).
  • A partially isolated application is one that insists on finding certain components in the specified directory while allowing other components to be located elsewhere and discovered through Windows normal search path.
  • Registration-free COM, as discussed in this blog, is a partial isolation solution targeted at COM controls.
Side-by-Side Assemblies
  • An assembly is merely an association of one or more resources an executable may include to access the functionality represented in the assembly. An assembly manifest has its own format, distinct from an application manifest . The assembly manifest lists the components and resources that comprise the assembly. Components can be any type of resource that an executable might include or map to at runtime, including icons, bitmaps, configuration files, conventional DLL's COM libraries, etc. (Caveat however: the scope of the techniques described here have not been tested on anything other than COM controls!)
  • A side-by-side assembly is an advanced method of storing and registering a set of version-compatible components under the Windows system installation directory. The purpose is to allow different version sets of components to be registered globally and referenced as necessary by individual applications.
  • Microsoft deploys a handful of standard side-by-side assemblies that are available to all executables. The most commonly used one is the Shell Common Controls version 6.0 (Comctl32.dll) assembly.
  • For some time now, Visual DataFlex application manifest files have included a dependency node reference to the Common Controls 6.0 assembly. You can see this in a standard Visual DataFlex application manifest as a tree of XML elements comprising a <DEPENDENCY>node.
Manifest Documentation
  • The cited MSDN articles include topics specific to the structure of manifests. Information in these topics include:
    • Description of allowed elements and attributes.
    • Schema (careful, this is Microsoft’s own schema format, not an xsd or dtd).
    • Editorial: This documentation is a bit sparse and does not describe the intricate workings of manifests in great detail, but it does provide a high level picture of the breadth and depth of functionality available through use of manifests.
How is Registration-free COM achieved?

OK, so all this background information is well and good, but let's dig into how to put the technique into action.

In general, Registry-free COM is achieved:
  • By including in the Application Manifest the information for all referenced COM objects that is typically stored in the registry when the COM control hosting the objects is installed and registered (i.e., by using regsvr32.exe to register the control).
  • And, by deploying the .dll or .ocx file in the location the manifest specifies relative to the executable’s location. Typically, this is simply the executable’s directory, but it can be any directory that can be pathed to relative to the executable's location using standard relative path notation, for example, .\Controls\MyComControl.ocx to use a sub-directory of the executable's location named, "Controls". (If you want to use such relative pathing, after using the utility described below you will need to manually add the relative path into each <FILE>entry the utility adds to the application manifest.)
We at Anasazi Software, Inc., where I work, have created a utility and process for using it that extracts relevant information from the registry on a machine where the COM control of interest has been conventionally installed and adds that information to a target application manifest. The process goes like this:
  1. For a given imported COM package, append a <FILE>element to the manifest with a name attribute equal to the name of the dll or ocx file.
  2. Examine the Visual DataFlex package generated by the Studio's COM class generator. For each “Set psProgID” line in a COM control’s imported class package, locate the defined GUID in HKEY_CLASSES_ROOT\CLSID in the Registry.
  3. If the registry key is found, create a sub-element <COMCLASS>and populate its allowed attributes with corresponding information from the Registry.
  4. If there is an associated Typelib GUID in the Registry, create a sub-element of the element named <TYPELIB>and populate appropriately.
  5. Deploy the COM control (.dll, .ocx, etc.) in the same directory as the executable and the modified manifest file.
The Manifest Modifier Utility

I am happy to include as part of this blog a Visual DataFlex 16.0 source code workspace for the Manifest Modifier Utility we created. It's not a terribly complicated program, and I encourage you to examine it to understand how it works and modify it as you see fit to work in your environment and with your favorite redistributable COM controls. The reason you may need to modify it is that you may run across variations in how controls create their registry entries in a conventional installation that are not anticipated or accommodated in the utility as it stands. Or, you may find that the utility does most of the work for you, and you simply need to make adjustments to the resulting XML fragments in order for Windows to be happy running the application.

The Manifest Modifier has two modes. In its first mode, it examines .pkg files created by the COM Class Generator when importing COM controls in the Studio and creates a fragment manifest file with the same root name as the .pkg. In this fragment, it creates appropriate <FILE>entries that contain the same COM definition information that is typically placed in the Windows registry. In its second mode, it merges selected .pkg.manifest files into a targeted application manifest file. You can, and often will, run the second mode several times to import all necessary fragment manifest files into the application manifest.

Any time a new or updated COM import package is created in the Studio, use the Manifest Modifier to create a new fragment manifest file in sync with the COM package, and merge the fragment manifest into all application manifests that use the package’s COM controls. If the COM control’s entries already exist in the application manifest, they will be updated; otherwise, they will be appended as new.

Pleasantly, there is no need to regenerate or merge the fragment manifests each time a Visual DataFlex application is compiled. The Visual DataFlex compiler/linker will simply update relevant information in the manifest and ignore the isolation entries.

Here's what the Manifest Modifier looks like run in the first mode to generate a manifest fragment file for a COM control package:

Click image for larger version. 

Name:	ManifestModifier1.jpg 
Views:	1182 
Size:	71.7 KB 
ID:	4418

Here's what it looks like when run in the second mode to append a fragment manifest to a target application manifest:

Click image for larger version. 

Name:	ManifestModifier2.jpg 
Views:	990 
Size:	58.7 KB 
ID:	4417

You may have noticed in the first image above that the feedback window shows an error. This may or may not indicate a problem with the resulting manifest registration entries. Not all registry keys and values are required or implemented by all COM control producers, and the utility makes very little effort to make requirement decisions for you. I have found that if the application runs and the COM control behaves as I expect, it's safe to simple ignore the error raised by the Manifest Modifier utility.

Final Thoughts

As touched upon above, Microsoft's documentation of this technique seems to be short on details. I am left with the impression that there may be a fair amount of undocumented features or behaviors that we'll want to be on the look out for. By itself, this realization would make me shy away from using this technique, but because Windows is very picky about the formatting and included information in a manifest and generates an error to the user that the application may not be installed correctly if Windows does not like the manifest, then it has been my experience that anything I do wrong in creating the manifest shows up very quickly upon launching the referenced application.

Not all COM controls can be registered in an application manifest. Controls that are managed by Windows as a registered side-by-side assembly should not be referenced in a manifest as an isolated module. For instance, though not a COM control, Microsoft’s Common Controls v6 must be referenced as a <DEPENDENCY><DEPENDENTASSEMBLY>not as a <FILE>isolated reference. Attempting to do so will cause Windows to fail application launch because it knows this file has a public side-by-side registration and does not allow it to be simply isolated. You'll also probably want to shy away from trying to isolate the COM controls that Visual DataFlex itself now contains or contains in the future because the Visual DataFlex runtime files likely don't exist in the same folder as your application. It is possible, however, to create an all-in-one deployment of the Visual DataFlex runtime and your own app, but that's definitely a topic for another time!

Not all makers of COM controls follow the rules to the letter when creating COM entries in the Registry. Creating the manifest <FILE>entries may fail or the entries may need to be altered manually in order to get the control to behave in isolation. Let trial and error be your guide. If you use the Manifest Modifier and discover any such variances that seem to be more widely in use than just one maker's choice (or mistake), consider updating the Manifest Generator registry parsing logic and share it with the rest of us!

Thanks for taking time to explore this technique in this blog entry with me. Thanks to Data Access for encouraging me to document and inviting me to share this information. I welcome your feedback and encourage you to experiment with this technique and utility if it will be of value in your deployment environment.

Dan Levene
Chief Technology Officer
Anasazi Software, Inc
Phoenix, AZ, USA
dlevene@anasazisoftware.com

Post Script

As a bonus to my presentation at Synergy 2011, I also touched on a technique for embedding the manifest directly into the executable making it unnecessary to deploy the .manifest file as a companion. This is a good topic for another time, perhaps, but if you're interested, follow the link to the MSDN on-line article for Microsoft's manifest command line tool, MT.exe (located in the same MSDN area under a topic called "Side-by-side Assembly Development Tools). If you choose to explore this technique, be sure to test the resulting executable in all target operating system environments in which you expect to deploy the application. Remember, manifests were not supported prior to Windows XP, so an executable with an embedded manifest will very likely not launch on Windows 2000 or prior OS versions.

Updated 21-Jun-2011 at 01:55 PM by Stephen W. Meeley

Tags: dan levene
Categories
Uncategorized

Comments

  1. Jakob Kruse's Avatar
    Still great stuff Dan, thanks for putting it all in writing!
  2. Michel Boisvert's Avatar
    Thanks Dan for sharing this, it's really helpfull !
  3. Peter Bragg's Avatar
    Thanks for this Dan - a LOT of developers are going to find this VERY useful. Much appreciated.
  4. Emil's Avatar
    Thanks Dan,

    I used your utility to isolate our application and it works like a charm!
  5. Martin's Avatar
    Thanks Dan for your Help, we now have all the Codejock ocx's working side by side with the manifest embedded in the exe. So all we have to install is the Crystal Runtime and the Application Protection Plus dll.