检索Windows版本"1511"

Rob*_*Rob 3 .net c# windows-10

最新版本的Windows 10(目前为Insider Preview)标记为:

版本1511(OS Build 10586.3)

查看"关于Windows"时(开始>运行> winver)

使用适当显示的控制台应用程序,返回的Windows版本System.Environment.OSVersion.Version是10.0.10586.0,它既不包含winver报告的版本的"1511"或".3"组件.

有做似乎是在注册表中的琴弦下HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion,例如ReleaseId这将提供这些信息,但是这将依赖于实现的细节,而不是一个API的合同.

简而言之,是否有一个(文档化的)API提供Windows 10版本,如winver/或帮助>关于Windows组件,如记事本,可从.net应用程序调用?

dxi*_*xiv 7

以下是一些间接证据表明没有 API来获取"1511"字符串(除了从"ReleaseId"注册表值中读取它).这不是一个绝对的证据,它可能不是你想要的答案,但这就是我现在所拥有的.

使用sysinternals的ProcMon记录"winver"运行表明确实已经查询了注册表项,正如@SörenKuklau已经指出的那样.

winver.exe RegQueryValue HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseID SUCCESS Type: REG_SZ, Length: 10, Data: 1511
Run Code Online (Sandbox Code Playgroud)

根据ProcMon的报告,RegQueryValueExW用于"ReleaseID"的调用堆栈如下所示.

 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
Run Code Online (Sandbox Code Playgroud)

因此,winver.exe从sh​​ell32.dll调用ShellAboutW,它会打开对话框并填充数据.执行此操作时,它会读取"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseID"注册表值,该值返回"1511".

确实在shell32.dll中找到了值"ReleaseID"作为硬编码字符串.此外,唯一带有"ReleaseId"字符串的其他System32 DLL是SettingsHandlers_nt.dll和WSShared.dll - 但两者都没有被winver.exe加载,并且两者都具有不同的"ReleaseID"大写(最后的小写"d",一件事).这强烈暗示:
(a)传递给RegQueryValueExW的字符串是shell32.dll中硬编码的字符串;
(b)其他MS代码具有相似的字符串硬编码,大概是因为没有API来获取它.

这仍然留下了可能由shell32.dll通过其他API公开相同的"1511"信息(或至少"ReleaseID"值名称)的可能性.例如,有可能在调用栈中偏移8,9,10处的"Ordinal897"调用之一实际上可能是类似"GetWin10RelID(LPTSTR lpRellD,int nMaxChars)"的函数; 并且它也可能通过名称而不是序数导出,并在将来的SDK中记录.但是,目前这些是由序数导出的匿名函数,没有文档,也不保证下次更新shell32.dll时它们甚至会保持相同的顺序.

  • releaseid 不再适用于 21h1,而是现在使用 displayversion。旧版本不存在 (2认同)

Sör*_*lau 5

FWIW,Process Monitor建议这样winver做只是查询ReleaseId。因此,也许这确实是“ 1511版”品牌的全部内容。

23:59:30,6022870    winver.exe  7004    RegQueryValue   HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseID SUCCESS Type: REG_SZ, Length: 10, Data: 1511
Run Code Online (Sandbox Code Playgroud)

winver再次启动时,立即反映将注册表值更改为随机值。删除该值将winver显示一个空字符串。

因此,尽管没有很好地包装在API中并且可能不受支持,但这似乎可以解决问题:

using (var hklmKey = Microsoft.Win32.Registry.LocalMachine)
using (var subKey = hklmKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"))
{
     if (subKey != null)
     {
         string release = subKey.GetValue("ReleaseId") as string;

         if (release != null)
             retVal += " Version " + release;
     }
}
Run Code Online (Sandbox Code Playgroud)