0 out of 3 rated this helpful - Rate this topic

Specifying a Default Activation Context

When your application or component creates a new process, Windows searches for a default application manifest. Note that a manifest included as a resource in the application takes precedence over an external manifest. The default activation context is the first activation context that is active before any other activation context has been activated. This activation context is always active unless you activate other contexts. If you define ISOLATION_AWARE_ENABLED when you compile your application or component, calls like CoCreateInstance, LoadLibrary, and CreateWindow can perform automatic context management.

The loader allows an application to specify its default activation context by two methods. You can put the manifest file in the resources of the executable and the loader will find it. This is the same as putting the manifest file in the executable's resource table. You can place the manifest in a file named Myapp.exe.Manifest in the same directory as Myapp.exe, and the loader finds it while looking for Myapp.exe.

If you use none of these methods, the application starts with the system default activation context, which contains a minimal set of assemblies.

A better way of using automatic context management is by compiling your application with ISOLATION_AWARE_ENABLED defined. The recommended method is to set this on the compiler's command line for the entire project being built rather than being set in individual source files or headers. This makes most Win32 APIs aware of activation contexts and how to manage them. Instead of having to do your own activation context management, you simply need to place a manifest in your resource table at resource ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID (numeric value 2), of type RT_MANIFEST (numeric value 24.) Functions such as CreateWindow, CoCreateInstance, and SendMessage then automatically activate this context before making the actual call.

Note that if you compile with ISOLATION_AWARE_ENABLED defined, you cannot also do your own activation context management. With ISOLATION_AWARE_ENABLED defined, Windows ignores any dynamic activation context creation your application may attempt to do between ActivateActCtx and CreateWindow calls. This means that when your application uses ISOLATION_AWARE_ENABLED you must make sure that the manifest contains a complete list of all assemblies that your component requires.

 

 

Send comments about this topic to Microsoft

Build date: 2/3/2012

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
When to use resource IDs 1, 2, or 3 for loading a manifest

The MSDN documentation is unclear about when to use the resource IDs 1, 2, or 3 for loading a manifest (RT_MANIFEST) from a resource .rc file. The purpose is usually to establish an activation context for using COMCTL32.DLL version 6 to get XP-style themes.

Briefly the usage is as follows.

Resource ID 1 (CREATEPROCESS_MANIFEST_RESOURCE_ID) is activated implicitly when the .EXE is executed. The activation context blankets all DLLs implictly or explicitly loaded by the .EXE.

Resource ID 2 (ISOLATIONAWARE_MANIFEST_RESOURCE_ID) intercepts static imports of the DLLs listed in the manifest for this module only. Also, if the module is built as a USRDLL with MFC version 7 or later it activates the context for dynamic use when execution control reaches any entry point in the DLL, via AFX_MANAGE_STATE(AfxGetStaticModuleState()).

Resource ID 3 (ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID) is never used by the Windows loader. It is used only in explicit user code that wants to manually load and establish an activation context. In particular it is used by the #define intercepts declared by setting ISOLATION_AWARE_ENABLED=1 before including windows.h. For the macro implementation of ISOLATION_AWARE_ENABLED see WinBase.inl, WinUser.inl, Commctrl.inl, Comdlg.inl, and Prsht.inl. The intercept macros wrap the XP-theme-aware APIs such as CreateWindowEx() and LoadLibrary() in order to activate the V6 context, which is loaded from resource ID 3 - WinBase.inl WinbaseIsolationAwarePrivatetRgzlnPgpg actCtx.lpResourceName = (LPCWSTR)(ULONG_PTR)3. The context is wrapped around each API call such that the context is activated upon each API call and deactivated upon each API return.

A module can only implement one of the resource IDs 1, 2, or 3. Windows XP or later will refuse to load the module if implements multiple IDs (see JunFeng Zhang's blog article cited below).

Note: A resource ID other than 1 is sometimes useful in an EXE. For example resource ID 2 or 3 should be used if your EXE hosts third-party COM objects that might display a UI. For example, the Microsoft Management Console (MMC.EXE) uses resource ID 3 because it hosts COM snap-in DLLs. (A 3rd party MMC snap-in DLL could have been written for Windows 2000 and thus might be unprepared to handle comctl32 V6.)

Use of ISOLATION_AWARE_ENABLED is a kludge and should be avoided. This is because it requires that you have control over all of the source code in your application including all DLLs. And it omits some important APIs such as MessageBox, forcing you to include special handling. A much better approach is to simply declare CREATEPROCESS_MANIFEST_RESOURCE_ID. If you are writing a DLL that shows a UI intended for use by 3rd parties, use ISOLATIONAWARE_MANIFEST_RESOURCE_ID and define a C++ RAII class that you instantiate at each DLL import entry point. See http://msdn.microsoft.com/en-us/library/aa375197.aspx.

The best documentation available from Microsoft is at http://blogs.msdn.com/junfeng/archive/2007/06/26/rt-manifest-resource-and-isolation-aware-enabled.aspx (JunFeng Zhang's Microsoft blog).