Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
124 views
in Technique[技术] by (71.8m points)

c# - Retrieving Windows version "1511"

The latest release of Windows 10 (currently Insider Preview) is badged as:

Version 1511 (OS Build 10586.3)

when looking in "About Windows" ( Start > Run > winver )

Using an appropriately manifested console application, the Windows version returned from System.Environment.OSVersion.Version is 10.0.10586.0, which contains neither the "1511" or ".3" components of the version reported by winver.

There do appear to be strings in the registry under HKLMSOFTWAREMicrosoftWindows NTCurrentVersion such as ReleaseId which would provide this information, however this would be relying on an implementation detail rather than an API contract.

In short, is there a (documented) API that provides the Windows 10 version as shown by winver and/or Help > About in Windows components such as Notepad which is callable from a .net application?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is some circumstantial evidence that there is no API to get the "1511" string (other than reading it off the "ReleaseId" registry value). It's not an absolute proof, and it may not be the answer you sought, but that's what I have at this point.

Logging a "winver" run with sysinternals' ProcMon shows that the registry key is indeed queried, as @S?ren Kuklau indicated already.

winver.exe RegQueryValue HKLMSOFTWAREMicrosoftWindows NTCurrentVersionReleaseID SUCCESS Type: REG_SZ, Length: 10, Data: 1511

The call stack at the point of that RegQueryValueExW for "ReleaseID" is the following, as reported by ProcMon.

 0 ntoskrnl.exe   NtQueryInformationFile + 0x3d50
 1 ntoskrnl.exe   NtOpenThreadTokenEx + 0x258c
 2 ntoskrnl.exe   setjmpex + 0x3963
 3 ntdll.dll      ZwQueryValueKey + 0x14
 4 KernelBase.dll MapPredefinedHandleInternal + 0x729
 5 KernelBase.dll RegQueryValueExW + 0xed
 6 SHCore.dll     SHQueryValueExW + 0xdd
 7 SHCore.dll     SHQueryValueExW + 0x32
 8 shell32.dll    Ordinal897 + 0x86f
 9 shell32.dll    Ordinal897 + 0xb8b
10 shell32.dll    Ordinal897 + 0x304
11 user32.dll     IsDialogMessageW + 0x76e
12 user32.dll     IsDialogMessageW + 0x941
13 user32.dll     IsDialogMessageW + 0x866
14 user32.dll     DispatchMessageW + 0x689
15 user32.dll     SendMessageW + 0x395
16 user32.dll     SetWindowLongPtrA + 0x979
17 user32.dll     DialogBoxIndirectParamAorW + 0x18c
18 user32.dll     DialogBoxIndirectParamAorW + 0x52
19 user32.dll     DialogBoxParamW + 0x85
20 shell32.dll    SHELL32_PifMgr_OpenProperties + 0x223d
21 shell32.dll    ShellAboutW + 0x72
22 winver.exe     winver.exe + 0x11d3
23 winver.exe     winver.exe + 0x1516
24 kernel32.dll   BaseThreadInitThunk + 0x22
25 ntdll.dll      RtlUserThreadStart + 0x34

So, winver.exe calls ShellAboutW from shell32.dll, which opens the dialog and fills-in the data. While doing this, it reads the "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionReleaseID" registry value, which returns "1511".

The value name "ReleaseID" is indeed found as a hardcoded string in shell32.dll. Moreover, the only other System32 DLLs that carry a "ReleaseId" string are SettingsHandlers_nt.dll and WSShared.dll - but neither is loaded by winver.exe, and both have different capitalizations for "ReleaseID" (lowercase "d" at the end, for one thing). This strongly hints that:
(a) the string passed into RegQueryValueExW is the one hardcoded in shell32.dll;
(b) other MS code has the similar string hardcoded, presumably because there is no API to get it.

This still leaves open the possiblity that the same "1511" information (or at least the "ReleaseID" value name) could conceivably be exposed by shell32.dll through some other API. It is possible, for example, that one of the "Ordinal897" calls at offsets 8, 9, 10 in the call stack may in fact be a function like "GetWin10RelID(LPTSTR lpRellD, int nMaxChars);" and it is also possible that it might get exported by name instead of ordinal and be documented in future SDKs. However, for the time being those are anonymous functions exported by ordinal, with no documentation, and no guarantee that they'll even keep the same ordinal next time shell32.dll is updated.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...