3

We had a project built for Win2K, then WinXP, then Win7 that has now been converted from a 32-bit Win7 program using VS2010 to a 64-bit Win10 program using VS2017. The VS2017 project was created from scratch and the old sources where then imported and updated as needed.

When I created the new project, I set the Target Platform (in the project's Configuration, General section) to Windows 10 and since I have no special needs, I set the project to build a manifest automatically.

Today I noticed that the dialog we have that shows the current Windows version info in the program says they we are running under Windows 8.1, internal version number 6.2. When I looked up the GetVersionInfo function I found out that it "lies" for programs that do not have a manifest saying they target Windows 10.

My question is in two parts:

  1. Since I used the VS2017 to target Windows 10 and build the manifest automatically, why is the function that only lies to programs that are NOT targeted to Windows 10 lying to my program? Shouldn't it have built the manifest correctly if it is going to do it at all?
  2. If VS2017 cannot or will not correctly target my program for Windows 10, can anyone help me find an example of how to manually do that with a plain C project? (Microsoft is not helpful with comments like "just add the necessary SXS symbols to your .rc file" -- I'm not going to randomly stick code in the .rc file by hand, hoping I accidentally stick it is the right place!)

I freely admit my ignorance of the manifest stuff. To date, I have not knowingly run into any situation where I needed to know about it.

[EDIT] Just a minor comment for the "this is a duplicate" crowd. My program doesn't CARE what version of Windows it finds, but it needs to REPORT as much detail about that version as possible. We display the information in one of our dialogs (and write it to a file) that we use when supporting customers. This allows us to ensure we build a test system with the exact same Windows as the customer. The primary focus of the "duplicates" is to ensure a program is running on the correct version of Windows, while mine is reporting all of the Windows version info I can find, so to me, this is NOT actually a duplicate of the others, although the RtlGetVersion() function (thanks @RemyLebeau) appears to solve both types of problem.

Steve Valliere
  • 1,119
  • 7
  • 12
  • 1
    You might find [this](https://learn.microsoft.com/en-us/windows/desktop/sysinfo/targeting-your-application-at-windows-8-1) interesting – Jabberwocky Oct 30 '18 at 15:48
  • 1
    This is documented, and the subject of tens if not hundreds of posts here on Stack Overflow. It's time to do some research. – David Heffernan Oct 30 '18 at 16:21
  • 1
    VS doesn't add the `` element to the application manifest automatically, so you have to manually add a manifest snippet containing a `` element as described in the link posted by @Jabberwocky. – zett42 Oct 30 '18 at 16:22
  • @Jabberwocky: That is exactly the article I was referencing that confused me. It shows some SXS symbols then says "You can also add this to your .rc file if you already have it defined." And I do not understand that incredibly vague statement. – Steve Valliere Oct 30 '18 at 20:24
  • Good ol' Microsoft. They have a setting for Target Platform, but no option to actually use it where needed. – Steve Valliere Oct 30 '18 at 20:27
  • 2
    This is all moot if you simply stop using `GetVersionEx()` altogether and use a different API that doesn't lie to unmanifested apps to begin with, such as [`RtlGetVersion()`](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-rtlgetversion), or `GetFileVersionInfo()` of a system DLL like `kernel32.dll` as MSDN suggests. – Remy Lebeau Oct 30 '18 at 20:29
  • I have never encountered the functions you say Microsoft suggests. However, in the GetVersionEx docs, Microsoft actually recommends the version helper functions from https://learn.microsoft.com/en-us/windows/desktop/SysInfo/version-helper-apis Unfortunately, they are great for things like ensuring minimum version, but lousy for GETTING the version info. I will, hoever, look into the functions that @RemyLebeau suggests. Thanks! – Steve Valliere Oct 31 '18 at 11:30
  • @RemyLebeau do you have an example that shows how to use GetFileVersionInfo() on a system DLL to get *ALL* of the same data returned by RtlGetVersion()? I don't have the DDK, so I cannot use RtlGetVersion() since it requires DDK headers, according to the documentation. If it didn't require the DDK, it would be perfect, though. – Steve Valliere Oct 31 '18 at 15:16
  • 1
    @SteveValliere you do not need the DDK to use `RtlGetVersion()`. You could simply copy the declarations from MSDN and paste them into your own code, and then use `GetProcAddress()` to access the function at runtime. The [linked duplicate](https://stackoverflow.com/a/36545162/65863) has an example of that. – Remy Lebeau Oct 31 '18 at 17:43

1 Answers1

1

Proceed like this:

First create a manifest file in your project folder and call it for example manifest.xml, then add it to your project in the Solution Explorer:

enter image description here

It should have this content:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"></supportedOS>
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"></supportedOS>
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"></supportedOS>
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>
    </application>
  </compatibility>
</assembly>

Then right click on your project in the Solution Explorer. And modify the as shown below:

enter image description here

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • Actually you can remove everything from the manifest except the XML header, the `` and the `` element (including its content). VS already creates the other parts from the project settings and will correctly merge these with the `` element. – zett42 Oct 30 '18 at 20:19
  • So, contrary to the Microsoft statement that confused me, there is NOTHING that goes into my .rc file! Thanks, I think I can handle this from here. – Steve Valliere Oct 30 '18 at 20:26