c# - 如何在 Windows 11 中找到 Windows 产品名称?

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

昨天发布的 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 Enterprise”,而不是“Windows 11 Enterprise”。
注册表中似乎只有一个地方包含文本“Windows 11”,那就是 BCD 部分(引导配置),它也可以重命名,所以我不想碰它。
到目前为止,我只确定了几种方法来判断我是否在 Windows 11 上运行:

  • 调用 WMI 以查询 Win32_OperatingSystem 并检查 Name 属性,该属性仅显示“Windows 11”。这是不完整的(它不包括诸如“企业”之类的 SKU),而且 WMI 相对较慢且有点脆弱,因此对于我的用例来说,它不是一个可以接受的解决方案。
  • 检查内部版本号以查看它是否高于 21996(测试版)或 22000(首次公开发布)。如上所述,这不包括 SKU,并且需要一些手动拼图才能构建完整的字符串。
  • 运行 sysinfo并解析输出。这很慢,而且可能很脆弱(我没有检查过,但输出可能被本地化为不同的语言)。
  • winver知道,但它是一个 GUI 应用程序,所以我不能以编程方式准确地查询它。

  • 有没有人对如何以高性能和完整的方式从我的操作系统中获取字符串“Windows 11 Enterprise”(或“Windows 11 Pro”等,视情况而定)有任何其他想法? WMI、sysinfo 和 winver 从哪里获得它?
    我需要从 .NET 库执行此操作,但 P/Invokes/ native 函数调用是可接受的解决方案。

    最佳答案

    把它留在这里,以便我以后可以找到它:
    似乎 Windows 本身(例如 winver)从 Windows 品牌中获取此信息 - 特别是来自 %WinDir%\Branding\Basebrd\en-US\basebrd.dll.mui 中的资源表.
    要访问这个可以使用 %WinDir%\System32\winbrand.dll 中的私有(private) 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%!"));
    
    

    关于c# - 如何在 Windows 11 中找到 Windows 产品名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69460588/

    相关文章:

    c# - 使用 System.IO.Packaging 生成 ZIP 文件

    windows - 发出错误检查通过 VBScript 运行的批处理文件

    c# - 如何从字典中获取键和值

    c# - 比较不可为 null 的 `int` 与 `null` (LINQ)

    c# - 是否可以通过一个连接在 .Net 中实现异步 Web 服务调用?

    c# - LINQ - 按最后一位数字连接两个列表

    c# - VB 编译器不隐式转换为对象?

    windows - WinInet 与 WinHttp(服务或类似服务的进程)

    database - SQLite 安全选项我需要加密数据库吗?

    c# - 窗口最小化后不恢复