Jaa


The Win32Manifest Switch

In order for managed applications to play nice with Vista, specifically to avoid virtualization when writing to special areas of the registry and filesystem, the VS2008 and .NET 3.5 C# and VB compilers write a manifest in the native resource section of EXEs. The C# and VB compilers now support a pair of switches, "Win32Manifest" and "NoWin32Manifest," to manage this embedding.

The MSDN documentation on these switches is pretty good. Read it carefully and you'll notice a comment saying "the compiler inserts a standard application name 'MyApplication.app' into the xml" to workaround a problem on Win2K3. This is not exactly true. Yes, the <assemblyIdentity> element is present in the manifest to work around a defect on Win2K3, but the compiler doesn't insert this element into the manifest. Instead the manifest is treated as opaque data by the compiler and simply put in the correct place of the PE. If you don't specify one and you don't tell the compiler not to put the default in, then the compiler blindly writes in a default, static manifest.

If you need to write your own custom manifest, maybe to specify a different execution privilege level, you gotta get it right (duh). Combine the absence of compile-time verification of the manifest with the fact that the manifest section of a PE is interpreted by the Windows loader at runtime, and you can produce spectacular failures from seemingly innocuous typos. But there is one failure that is more subtle and easily goes unnoticed without thorough testing.

On Win2K3, if your managed application has an embedded manifest, and the manifest does not contain the optional <assemblyIdentity> element, then the CLR will not be able to locate your exe.config file and any assembly redirects (or anything else) you may have specified in there will not be honored. Interestingly, the "name" and "version" attributes of the <assemblyIdentity> element need not be meaningful to work around the problem. The element just has to be present, contain those attributes, and be well-formed.

That's the important part of this post, but perhaps you're wondering how we arrived at the decision to label every app produced by the managed compilers as "MyApplication.app" in the manifest...

The original design of this feature, writing a manifest into the output, called for embedding a static file. There was not a strong motivation to add validation or comprehension of its contents. Our original default manifest didn't contain the <assemblyIdentity> element. No need. We were just trying to address Vista's UAC needs. But during testing we uncovered the defect on Win2K3 and then the workaround for it. At that point we had a choice to begin understanding the manifests and to place the correct application name in the "name" attribute, or continue to use a static manifest but use a meaningless application name. We chose the latter. There's no good reason or discoverable way to look at this name programmatically as far as I know. And expanding the scope of the feature and resetting the testing was just not worth the gain.

Comments