How to add the application compatibility section with Visual C++ 2008?

If you wonder what I’m talking about when mentioning the compatibility section, have a look at my previous blog entry.

To start with, I added a Compatibility.manifest file to my project:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">

      <application>

         <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>

         <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>

      </application>

   </compatibility>

</assembly>

 

I then specified $(InputDir)\Compatibility.manifest in the Configuration Properties/Manifest Tool/Input and Output/Additional Manifest Files field in the project properties dialog. This automatically added /manifest ".\Compatibility.manifest" to the MT.EXE command line that would be used at build time.

Not too sure it would work; I then rebuilt a small C++ program and got:

\Compatibility.manifest : manifest authoring warning 81010002: Unrecognized Element "compatibility" in namespace "urn:schemas-microsoft-com:compatibility.v1".

 

I must be using an old MT.EXE version. I turned off the Suppress Startup Banner, turned on the Verbose Output and rebuilt:

Microsoft (R) Manifest Tool version 5.2.3790.2076

Copyright (c) Microsoft Corporation 2005.

All rights reserved.

\Compatibility.manifest : manifest authoring warning 81010002: Unrecognized Element "compatibility" in namespace "urn:schemas-microsoft-com:compatibility.v1".

 

Let’s dir C:\MT.EXE /S /B and look at the versions of MT.EXE I have on my hard-disk:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\mt.exe
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\x64\mt.exe
C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\mt.exe
C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\x64\mt.exe

 

No surprise as I have both VS 2008 SP1 and the released Windows 7 SDK installed. Let’s launch the one I hope is the one I’m using:

D:\>"C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\x64\mt.exe" /?
Microsoft (R) Manifest Tool version 5.2.3790.2076
Copyright (c) Microsoft Corporation 2005.
All rights reserved.

Usage:

 

So I am building with the publicly latest and greatest version of MT.EXE! I’m guessing I’ll ignore the warning but I need to make sure this works.

First, I loaded my program executable with the Visual Studio Resource Editor (File/Open/File… /Open With… ) to look at the MANIFEST resource: yes, the setting was there, as was the Side-by-Side information.

But I wanted to go a step further so although I said in my previous blog entry that it was an obscure topic to me, I looked at the sample on the ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION Structure page, but it crashed on my machine. I kept playing around and ended up with the following code:

GUID WIN7_CONTEXT_GUID = {0x35138b9a, 0x5d96, 0x4fbd, {0x8e, 0x2d, 0xa2, 0x44, 0x02, 0x25, 0xf9, 0x3a}};

GUID VISTA_CONTEXT_GUID = {0xe2011457, 0x1546, 0x43c5, {0xa5, 0xfe, 0x00, 0x8d, 0xee, 0xe3, 0xd3, 0xf0}};

HANDLE activationContextHandle = GetModuleHandle(NULL);

SIZE_T bufferSize = 0;

QueryActCtxW(QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE, activationContextHandle,

             NULL, /*ACTIVATION_CONTEXT_INFO_CLASS::*/CompatibilityInformationInActivationContext,

             NULL, 0, & bufferSize);

if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {

   _ASSERTE(bufferSize > 0);

   vector<BYTE> p(bufferSize);

   if (QueryActCtxW( QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE, activationContextHandle,

                     NULL, /*ACTIVATION_CONTEXT_INFO_CLASS::*/CompatibilityInformationInActivationContext,

                     & p.front(), bufferSize, &bufferSize)) {

      ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION * acci = reinterpret_cast<ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION *>(& p.front());

      DWORD dw = acci->ElementCount;

      COMPATIBILITY_CONTEXT_ELEMENT * ce = acci->Elements;

      while (dw) {

         if (ce->Type == ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS) {

            if (ce->Id == WIN7_CONTEXT_GUID) {

               wcout << L"Windows 7 is supported" << endl;

            }

            if (ce->Id == VISTA_CONTEXT_GUID) {

               wcout << L"Windows Vista is supported" << endl;

            }

         }

         ce++;

         dw--;

      }

   }

}

 

I ran it and got:
Windows Vista is supported
Windows 7 is supported

Voilà!

Como de costumbre, nous terminons avec une liste de ressources:

· Input and Output, Manifest Tool, Configuration Properties, <Projectname> Property Pages Dialog Box

· Understanding Manifest Generation for C/C++ Programs

(Thanks to everyone who answered my e-mails while working on this. You know who you are!)