Retrieve Build Version (Windows 8.1)

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
Anyone have an idea for retrieving the build version (reliably) in Windows 8.1? Windows 8.1 marked the deprecation of a few functions including GetVersion(Ex), which is silly because now the function returns Windows 8 build information, and the only thing accurate IMO is the major version because both are 6 between Windows 8 and Windows 8.1.

Microsoft says that the version helper API's superseed the GetVersion/GetVersionEx functions, yet it doesn't help me to determine that the OS is X or greater than X if I want to write an informational program that retrieves specific build information.

It's quite easy to write functions utilizing VerSetConditionMask, and VerifyVersionInfo to test version information and compare it to the known build numbers, so I don't really need to use those functions directly, but getting the build number hasn't been as easy as determining Windows 8 vs Windows 8.1.

I've only been looking at this for a half hour, but I figured I should post here while I continue my investigation. Why Microsoft decided to deprecate GetVersion(Ex), and considering the hassle(s) outlined in my post here, I honestly have no idea. I think they should've just kept these functions. It gets increasingly difficult to write programs that target multiple versions of the Windows operating system because of things like this..

One possibility that I haven't checked yet was the NetWkstaGetInfo() function. But that seems silly as well to dig into that library just for getting Windows version information.

The fact that this function is deprecated, means that some .NET interfaces for version information were broken as well and provide Windows 8 versioning instead of Windows 8.1 versioning information.

And to my knowledge, there is no such similar function that directly replaces GetVersion(Ex) asside from the direct set of BOOL functions to check whether the OS is a certain version or greater. I think it was a mistake Microsoft made here to think that those new set of version helper functions could meet the requirements of how the GetVersion(Ex) function was used in certain cases. Based on the documentation, it would appear that they had the idea that it was most commonly only used to test for operating system features for compatibility reasons, which would make sense as to why they introduced the version helper API in the first place, but they now leave developers like me behind when it comes to retrieving exact OS version information easily.
 
Last edited:
I used Powershell to get this. If you run the below command (Works also without Admin Privileges) -
Code:
$PSVersionTable.BuildVersion

you would get an output similar to mine -
Code:
Major  Minor  Build  Revision
-----  -----  -----  --------
6      3      9600   17400

You can also write this to a file and then compare -
Code:
$PSVersionTable.BuildVersion | Out-File "C:\Text.txt"

(You would need Administrator Privileges due to the Out-File commandlet).

I think that one can use Powershell using proper references in all of the .NET Framework Languages. (Please feel free to correct me if I am wrong)


-Pranav
 
Last edited:
I'm not using Powershell or .NET. I would like to avoid WMI if possible though for all of my solutions as it is slow.. I would like a solution suitable for C or C++ preferably. I know WMI can do it, but I don't want to take that path at all. WMI is ugly.

Environment.OSVersion is unreliable as of Windows 8.1 in .NET supposedly, and probably inherently could be marked as deprecated now too.


The OSVersion property returns the version reported by the Windows GetVersionEx function.
Note: The OSVersion property reports the same version number (6.2.0.0) for both Windows 8 and Windows 8.1.

From MSDN, they are obviously aware that this change to GetVersionEx() breaks Environment.OSVersion in .NET, yet they don't necessarily mark it as deprecated on this page. To the less avid researcher, one might think that it's meant to display 6.2.??? for Windows 8.1, but that's not true at all because they don't have the same build minor version at all.

They also continue to support this property in .NET 4.6 it looks like..

Unless they figure out how to change the getter for this property to support the same behavior in Win 8 and pre Win 8, and update it accordingly if the OS is Win 8.1 or Win 10, I think this is a disaster. I have yet to find any functions or properties which supersede Environment.OSVersion in .NET even though functions from the version helper API have came out to supersede GetVersion(Ex).

Hmm... Note that this would mean ditching the built-in .NET property and moving on to P/Invoke to use these functions which are to supersede GetVersion(Ex).
 
Last edited:
I'm going to decide to scrap every other check and just grab the version information from kernel32.dll using GetFileVersionInfo()...
 
Last edited:
I'm glad it's not just me who's been put out by this depreciation. I haven't moved some of my tools yet. Do they not realise that I might just want to write the information to a logfile, without actually directly acting on it in my program???

You'll have stumbled across it in your travels already, but to me, Microsoft's solution is just not reasonable: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724429(v=vs.85).aspx


For one thing, how am I supposed to deal with Windows 10 at the moment? They won't update the API until final release by policy, so I'd need to code my own function and set of constants. Or else put in a second test on the version of kernel32.dll or something like that as you've done, or not be able to distinguish it from Windows 8.1 (which is what they want). The whole thing is such a mind numbingly bad idea.
 
Last edited:
Do they not realise that I might just want to write the information to a logfile, without actually directly acting on it in my program???

This was/is my main concern and question. The documentation implies that they assume people only use these functions for compatibility reasons as far as I read, and not at all for purely informational purposes.

Windows 10 can be detected as long as we can GUARANTEE to know what the major and minor versions are. You can use the VerSetConditionMask, and VerifyVersionInfo functions. The problem is that it's not as easy to guess anything else other than the major and minor version to test what OS the user is running, and there are other parts to a build number/string other than just the major and minor versions. That's where I haven't quite figured out how to get such information reliably.

The kernel32.dll method as I've proved myself is ONLY accurate for getting the major and minor version numbers too, so even though I've found a 'hack', I still can't get the last of the build information for the OS because the rest of the numbers are specific to the file.

edit: Now on Windows 10 they have jumped it considerably.
Code:
10.0.9926.2.00010100.0.0.048

So you would have to set the condition mask to test for Major version 10, and Minor version 0. As for getting at least "9926.2", regardless of the other numbers... I have found no reliable way as of yet. The key is obviously withinn licensingdiag.exe... I just have yet to find time to digest what this program/utility is actually doing. My guess is that the key to solving this is within the 'VERSION.dll' listed as a dependency of licensingdiag.exe...
 
Last edited:
Do they not realise that I might just want to write the information to a logfile, without actually directly acting on it in my program???

This was/is my main concern and question. The documentation implies that they assume people only use these functions for compatibility reasons as far as I read, and not at all for purely informational purposes.

Windows 10 can be detected as long as we can GUARANTEE to know what the major and minor versions are. You can use the VerSetConditionMask, and VerifyVersionInfo functions. The problem is that it's not as easy to guess anything else other than the major and minor version to test what OS the user is running, and there are other parts to a build number/string other than just the major and minor versions. That's where I haven't quite figured out how to get such information reliably.

The kernel32.dll method as I've proved myself is ONLY accurate for getting the major and minor version numbers too, so even though I've found a 'hack', I still can't get the last of the build information for the OS because the rest of the numbers are specific to the file.

Yeah - I've just been coding this actually. In the end I guessed Windows 10's constants at 1000, and put in an extra (temporary) check for the Technical Preview at constant 0604, and I'll have to patch if they're wrong. It was not a clever move. Even if there was some backwards compatibility they were trying to maintain, and needed to provide the same function under a different name, it's better than the current state of affairs. [I'm thinking a bit like OpenFile vs. CreateFile]
 
I've made an edit niemiro just FYI :)

Same function under the same name, or even better yet, the same function which does similar things depending on what OS the user is on. Consistency for writing Windows code is just not friendly anymore. To write portable applications for the same platform; Windows, seems to become increasingly difficult as the years go by. An ideal goal is 3 versions of Windows for me, and in this case that will soon be Windows 10, Windows 8/8.1, and Windows 7. The big problem is the jump from 7 to 8 in my opinion, but they always seem to make changes that don't quite make sense to me.

This one depreciation really puts a kink in my neck. I think it might come down to simulating what VERSION.dll does, or dynamically linking to it based on what it exports.

edit: Huh...?

I see GetFileVersionInfo() and that's about it.
 
Now I'm more convinced that the key to this mystery is within SLC.dll or sppc.dll. OS information is probably tied in with the genuine check and retrieving such information. There's no way you can get all of those numbers from GetFileVersionInfo()
 
UPDATE: I need to correct my previous comment. GetFileVersionInfo() can be used to acurately get '10.0.9926', but the last number I get is a 0, which is wrong because it's meant to be a 2.

i.e. '10.0.9926.0' instead of '10.0.9926.2'
 
To be honest, I suspect the most reliable way is to read it out of the registry somewhere. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion seems pretty good, although I'm sure it's not the only place.
 
Another registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows
CSDVersion divided by 100 gives service pack level (e.g. 100 for SP1, 200 for SP2, etc.)
CSDBuildNumber could also potentially be useful [it's, well, build number]. However, this is duplicated into the key I gave in my last post though, so it's not particularly amazing. The build number does not match the one in BuildLabEx though - I think it's latest service pack build number vs latest servicing stack build number.
 
Last edited:

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top