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!)


 

Comments (0)