【问题标题】:How can I find the Windows product name in Windows 11?如何在 Windows 11 中找到 Windows 产品名称?
【发布时间】:2021-11-26 07:56:47
【问题描述】:

昨天发布的 Windows 11 几乎在所有地方都将自己报告为 Windows 10.0 - RtlGetVersion 说是 10.0,如果你问 VerifyVersionInfo 如果你是 11.0 或更高版本,它会说不是。

似乎没有新的 GUID 可以像 Windows 7、8、8.1 和 10 那样插入 app.manifest 以说“嘿,我支持 Windows 11”。

目前我依靠HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName 告诉我当前的 Windows 版本是什么,但在我升级的机器上,它仍然显示“Windows 10 企业版”,而不是“Windows 11 企业版”。

注册表中似乎只有一个地方包含文本“Windows 11”,那就是 BCD 部分(启动配置),也可以重命名,所以我不想碰它。

到目前为止,我只确定了几种方法来判断我是否在 Windows 11 上运行:

  1. 调用 WMI 来查询 Win32_OperatingSystem 并检查 Name 属性,它只是说“Windows 11”。这是不完整的(不包括“企业”等 SKU),而且 WMI 相对较慢且略显脆弱,因此对于我的用例来说,这不是一个可接受的解决方案。

  2. 检查内部版本号是否高于 21996(测试版)或 22000(首次公开发布)。如上所述,这不包括 SKU,并且需要一些手动的 jiggery-pokery 才能构建完整的字符串。

  3. 运行sysinfo 并解析输出。这很慢,而且可能很脆弱(我没有检查过,但输出可能会本地化为不同的语言)。

  4. winver 知道,但它是一个 GUI 应用程序,所以我无法通过编程方式准确地查询它。

是否有人对如何以高性能和完整的方式从我的操作系统中获取字符串“Windows 11 Enterprise”(或“Windows 11 Pro”等,视情况而定)有任何其他想法? WMI、sysinfo 和 winver 是从哪里获得的?

我需要从 .NET 库中执行此操作,但 P/Invokes/本机函数调用是可接受的解决方案。

【问题讨论】:

  • MS 长期以来一直提倡您根据需要测试功能,而不是检查操作系统版本。也许他们已经加倍努力,现在强迫你这样做?
  • 这不是用于机器决策,而是用于通知开发人员的错误报告 - 我希望能够知道我的应用程序在哪个版本的 Windows 上崩溃。
  • 将其命名为 Win11 是营销决策,与操作系统版本无关。它只是另一个 Win10 版本,在众多版本中,以内部版本号区分。如果是22000以上就知道是Win11了。
  • 您应该记录内部版本号,而不是营销名称。这也可以让您区分不同版本的 Windows 10(18363、19042 等)
  • 我们也记录了这一点,但我宁愿我们开始寻找正确的 Win11 版本或适当的正确 Win10 版本,而不是让开发人员早早越过他们的电线……我宁愿不负责永远维护我自己的操作系统版本映射。

标签: c# .net windows .net-core windows-11


【解决方案1】:

把这个留在这里,以便我以后可以找到它:

Windows 本身(例如 winver)似乎从 Windows 品牌获取此信息 - 特别是从 %WinDir%\Branding\Basebrd\en-US\basebrd.dll.mui 中的资源表。

要访问这个可以使用%WinDir%\System32\winbrand.dll 中的私有API。具体来说,函数BrandingFormatString接受一个宽字符串(LPW[C]STR)并返回一个宽字符串。

例如BrandingFormatString("%WINDOWS_LONG%") 在我的家用电脑上返回 "Windows 11 Pro"

我不知道结果字符串的生命周期语义,即是否/何时/如何释放它。

以下代码用作功能性概念验证 (C# 9.0):

using System;
using System.Runtime.InteropServices;

[DllImport("winbrand.dll", CharSet = CharSet.Unicode)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
static extern string BrandingFormatString(string format);

Console.WriteLine(BrandingFormatString("Hello World from %WINDOWS_LONG%!"));

【讨论】:

    【解决方案2】:

    我为桌面管理员创建了一个远程支持工具(请参阅http://www.appslife-rdt.appspot.com) 在 VB.Dot.Net 中,我使用了对 WMI 空间 Win32_OperatingSystem 的调用并取回了“名称”值。然后需要将其拆分以获得您需要的第一个对象。即

    Dim query2 As New SelectQuery("SELECT * FROM Win32_OperatingSystem")
    Dim searcher2 As New ManagementObjectSearcher(objManagementScope2, query2, QueryOptions)
            For Each mo As ManagementObject In searcher2.[Get]()
                               OSname = mo("Name")
            Next
    
            Dim array1 As Array = Nothing
            array1 = Split(OSname, "|")
            OSname = array1(0).ToString
    

    然后,OSname 会为您提供所需的“Windows 11 Pro”或“Windows XP Professional”。

    如果需要,我还会从注册表中获取带有最新补丁更新信息的 OSVersion,如下所示...

    这是针对 10/11 客户端版本的:-

    .SetPropertyValue("sSubKeyName", "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Update\TargetingInfo\Installed\Client.OS.rs2.amd64") .SetPropertyValue("sValueName", "Version")

    这适用于 2019 年服务器版本:-

    .SetPropertyValue("sSubKeyName", "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Update\TargetingInfo\Installed\Server.OS.amd64") .SetPropertyValue("sValueName", "Version")

    希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      tldr - 在注册表中使用CurrentVersion 中的EditionIDCurrentBuild 似乎是确定Win10 与Win11 以及软件“版本”的可靠方法。 EditionID 在 Windows 10 专业版和 Windows 11 专业版上是“专业”,CurrentBuild >= ~22000 告诉你它是 10 还是 11。

      HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion 中的注册表值集合揭示了微软缺乏计划的感觉。 ReleaseId,这是一个随每个 Windows 10 版本而变化的数字(例如,190319092004、...),直到它在 Windows 10 20H2 的最后一次更改中更改为 @987654331 @。同时添加了DisplayVersion,并设置为20H2

      随后Windows 10 21H1发布,ReleaseId莫名停留在2009

      当前的 Windows 10 和 Windows 11 版本可以具有相同的DisplayVersion(例如,21H2,当 Windows 10 21H2 即将发布时)和ProductName(例如,Windows 10 Pro)确实令人头疼. (感谢@yaakov 发现我说是 21H1 的错误。)

      【讨论】:

      • Windows 11 有DisplayVersion = 21H2,这似乎是正确的,并且是 WinVer 所显示的。
      • Doh,你完全正确。我试图说明的一点是,还将有一个 Windows 10 21H2 - 它尚未发布,同时拥有 10 和 11 21H2 会很奇怪。谢谢指正。
      【解决方案4】:

      以下代码已在 Windows XP、7、10、11 上进行了测试。它适用于 32 位和 64 位操作系统。它适用于 32 位和 64 位应用程序。

      将生成以下字符串:

      • “Microsoft Windows XP,Build 2600,32 位”
      • “Windows 7 Ultimate,Build 7601,64 位”
      • “Windows 10 Enterprise LTSC 2019,版本 1809,内部版本 17763,64 位”
      • “Windows 10 专业版,版本 1909,内部版本 18362,64 位”
      • “Windows 11 专业版,版本 21H2,内部版本 22000,64 位”

      将代码放入静态构造函数中,使其只执行一次并将版本写入静态变量。

      static String ms_OperatingSystem;
      
      static Constructor()
      {
          try
          {
              String s_KernelPath = Path.Combine(Environment.SystemDirectory,"Kernel32.dll");
              FileVersionInfo k_Kernel = FileVersionInfo.GetVersionInfo(s_KernelPath);
      
              // on 32 bit Windows this will read the 32 bit hive instead
              using (RegistryKey i_HKLM = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
              {
                  using (RegistryKey i_RegVer = i_HKLM.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion", false))
                  {
                      // Kernel32.dll on Windows 11 has Product Version 10.0.22000.120
                      if (k_Kernel.ProductMajorPart == 10 && k_Kernel.ProductBuildPart >= 22000)
                      {
                          ms_OperatingSystem = "Windows 11";
      
                          Object o_Edition = i_RegVer.GetValue("EditionID"); // "Professional"
                          if (o_Edition is String)
                              ms_OperatingSystem += " " + o_Edition;
                      }
                      else
                      {
                          // "Microsoft Windows XP"
                          // "Windows 7 Ultimate"
                          // "Windows 10 Pro"  (same string on Windows 11. Microsoft SUCKS!)
                          ms_OperatingSystem = (String)i_RegVer.GetValue("ProductName");
                      }
      
                      // See: https://en.wikipedia.org/wiki/Windows_10_version_history
                      // Windows 10 older releases --> "2009" (invalid if DisplayVersion exists)
                      Object o_ReleaseID = i_RegVer.GetValue("ReleaseId");
      
                      // Windows 10 latest release --> "21H1"
                      // Windows 11 first  release --> "21H2"
                      Object o_DispVer = i_RegVer.GetValue("DisplayVersion");
      
                      // Use ReleaseID ONLY if DisplayVersion does not exist in registry!
                           if (o_DispVer   is String) ms_OperatingSystem += ", Version " + o_DispVer;
                      else if (o_ReleaseID is String) ms_OperatingSystem += ", Version " + o_ReleaseID;
      
                      ms_OperatingSystem += ", Build " + k_Kernel.ProductBuildPart;
      
                      if (Environment.Is64BitOperatingSystem) ms_OperatingSystem += ", 64 bit";
                      else                                    ms_OperatingSystem += ", 32 bit";
                  }
              }
           }
           catch (Exception Ex)
           {
              ms_OperatingSystem = Ex.Message;
           }
      }
      

      【讨论】:

        猜你喜欢
        • 2017-01-29
        • 1970-01-01
        • 2017-04-23
        • 2013-10-04
        • 2019-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多