WEBINAR: On-demand webcast
How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >
The .NET platform often receives all the attention when it comes to simplified and XCOPY deployment, but .NET does not have a monopoly on simplified deployment. In fact, the deployment story for native C++ applications is by far the best of any tool or language combination available for Windows. It offers XCOPY or minimal deployment for a large range of application types. Applications that use COM heavily have traditionally been the exception to the good-deployment-model story, but with registration-free activation, you can deploy these applications without a laborious installation process.
Earlier versions of Windows and Visual Studio had an obvious problem with system stability: They used system-wide deployment and subsequent component versioning that weren't really designed to be shared. COM was often chosen as a packaging model for components because of features such as cross-language support and enterprise services in COM+, and the shared-deployment model was a non-optional 'feature' that was forced on the application.
The traditional deployment model of COM was merely an implementation detail, and the COM activation APIs in the Windows SDK are sufficiently decoupled from the Registry to allow other deployment models. Windows XP and Windows Server 2003 support a deployment and activation model that uses a local XML file to store the information that Windows needs to locate and create a COM component. This deployment model is extended in Windows XP SP2 and .NET 1.1 to allow .NET components with a COM wrapper to also benefit from registration-free activation.
The COM activation information is stored in a Win32 manifest file, which is an XML file that sits in the same folder as the executable and has the name of the executable with .manifest appended. Manifest files are one of the cornerstones of the more robust deployment model that Win32 Side-by-Side (SxS) offers. My defining the component versions that the executable should use, a manifest file basically serves the same purpose as a .NET assembly manifest. A publisher can force an upgrade (in the case of a critical security patch or something similar) by deploying a component manifest, and an application vendor can 'upgrade' an application to use newer releases of components by shipping a manifest file that re-directs to the newer versions.
Manifest File Creation in Visual C++ 2005
Prior to Visual C++ 2005, there wasn't a lot of tool support for creating and maintaining manifest files. Developers were often forced to wade through cryptic error messages related to a missing attribute somewhere in a large XML file. Thankfully, Visual C++ 2005 has a wide range of options for manifest files, and you can achieve registration-free COM activation for both managed and native C++ applications simply by setting a few properties for a C++ project.
Figure 1 shows the project properties for a Win32 console project.
Figure 1: Isolated COM Properties for a C++ Project
As you can see, the Manifest Tool | Isolated COM tree node has been selected, and the name of a COM DLL has been added to the Type Library and Component file name text boxes (type libraries were usually shipped embedded with their parent component, but this wasn't mandatory). In this case, the COM DLL has been manually copied into the same folder as the C++ project, because referencing a COM DLL located somewhere else on the file system will cause that path to be recorded in the manifest file, and the development-time and deployment-time paths will nearly always be different.
You can embed application manifests within the EXE file or house them in a separate XML file. Any tool that supports viewing embedded resources in a file with the PE file format can view embedded manifests, but embedded manifests are not as convenient at development time when various settings need to be tweaked. By default, Visual C++ embeds the manifest as a resource, but you can modify this as shown in Figure 2.
Figure 2: Project Settings for a Stand-Alone Manifest File
The Activation Context APIs
Registration-free COM activation and the various other deployment facilities offered by Windows SxS obviously require runtime support from the operating system. You can query and manipulate the runtime aspects of SxS at runtime using the Activation Context APIs. The ACTCTX structure is the main workhorse of the API set; it provides a number of functions to work with ACTCTX structures (including the wonderfully named ZombifyActCtx). Using these functions, you can create an application context for a process that controls how DLLs, COM components, and Windows classes are located and loaded.
As the first part of this article showed, an application doesn't need to explicitly interact with the activation context APIs to take advantage of SxS. Application, publisher, and assembly manifest files will be the only way most applications interact with SxS, and developers don't need to take any special actions to make their applications SxS-compatible. Any COM activation technique.NET interop, #import, ATL smart pointers, or raw CoCreateInstance calls (which is where all the other technologies eventually end up)will work equally well with registration-free COM if the manifest file is correct.
About the Author
Nick Wienholt is an independent Windows and .NET consultant based in Sydney, Australia. He is the author of Maximizing .NET Performance from Apress, and specializes in system-level software architecture and development with a particular focus on performance, security, interoperability, and debugging. Nick can be reached at NickW@dotnetperformance.com.