Search code examples
winapivisual-c++visual-studio-2017

How to edit manifest in VS2017 C++ project?


In our application, we need to be able to determine Windows OS version. In the past, we used the GetVersionEx() function but it has been deprecated and it appears to stop on Win 8 (major=6, minor 2).

We'd like to use helper functions like IsWindows10OrGreater() but they require that apps define compatibility section in their manifests. However, we do not know how we can edit the manifest that is automatically generated by VS2017.

There are some on-line docs that claim that you can add/edit .manifest file under Resources folder. However, we could not see such files even in newly created projects. Adding them manually does not help - they are ignored during a build process.

How should this be done?


Solution

  • The easiest way to add the required manifest elements to Visual C++ is to add the following file to your project:

    settings.manifest

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
       <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
           <application> 
               <!-- Windows Vista -->
               <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
               <!-- Windows 7 -->
               <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
               <!-- Windows 8 -->
               <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
               <!-- Windows 8.1 -->
               <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
               <!-- Windows 10 / Windows 11 -->
               <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
           </application> 
       </compatibility>
    </assembly>
    

    Then make sure you have in your project settings:

    • Linker -> Manifest File -> Generate Manifest set to YES.

    • You should also have Enable User Account Control set appropriately.

    • Manifest Tool -> Input and Output have Embed Manifest set to YES

    See this blog post.

    Once you do this, you can then call GetVersion, GetVersionEx, VerifyVersionInfo, and use the VersionHelpers.h and they will all give you the "correct" answer. You will need to suppress C4996 for GetVersion or GetVersionEx, but that warning is just there due to the manifest behavior.

    Of course the real question: WHY do you think you need the OS version number? See this blog post.

    UPDATE: You should not use a version check as a substitute for a feature check. If you want to know if NetGetAadJoinInformation is available, then use explicit linking or delay-load DLLs and check for the function before calling it.