在C#中获取操作系统版本/友好名称

27

我目前正在进行一个C#项目。我想收集用户统计数据以更好地开发软件。我正在使用 C# 的 Environment.OS 功能,但它只显示操作系统名称,例如 Microsoft Windows NT

我想要能够检索实际已知的操作系统名称,例如 Windows XP, Windows Vista 或 Windows 7 等等。

这种可能性存在吗?


请查看此答案 https://dev59.com/CnRB5IYBdhLWcg3wl4Oc#2016557 - Bala R
请查看https://dev59.com/QXRA5IYBdhLWcg3wsgLq。 - Brandon E Taylor
可能是如何检测用户操作系统的重复问题。 - Offir
8个回答

60

添加 System.Management 的引用和 using 语句,然后执行以下操作:

public static string GetOSFriendlyName()
{
    string result = string.Empty;
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem");
    foreach (ManagementObject os in searcher.Get())
    {
        result = os["Caption"].ToString();
        break;
    }
    return result;
}

1
我的软件的一些用户在运行时会遇到ManagementObjectSearcher.Get()中的UnauthorizedAccessException异常。你有什么想法,为什么会出现这种情况? - Walt D
@WaltD,请在一个问题中提出这个问题,并在该问题中包含指向此答案的链接。 - ANeves
根据MSDN中的措辞,如果计算机上安装了WMI(如果!),那么有可能某些计算机没有安装WMI。对于这些计算机,这种方法很可能会失败。 - ANeves
1
@ANeves 我在这里提问了,但是没有人回答它。链接 - Walt D

12

你应该尽量避免在本地使用WMI。虽然很方便,但会付出性能代价。可以将其视为懒惰税!

Kashish提供的关于注册表的答案并不适用于所有系统。下面的代码应该可以,并且还包括服务包:

    public string HKLM_GetString(string path, string key)
    {
        try
        {
            RegistryKey rk = Registry.LocalMachine.OpenSubKey(path);
            if (rk == null) return "";
            return (string)rk.GetValue(key);
        }
        catch { return ""; }
    }

    public string FriendlyName()
    {
        string ProductName = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName");
        string CSDVersion = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CSDVersion");
        if (ProductName != "")
        {
            return (ProductName.StartsWith("Microsoft") ? "" : "Microsoft ") + ProductName +
                        (CSDVersion != "" ? " " + CSDVersion : "");
        }
        return "";
    }

2
在 Windows 11 上,这将报告,例如“Windows 10 企业版”。 - Mister Cook

9

添加一个.NET引用到Microsoft.VisualBasic。然后调用:

new Microsoft.VisualBasic.Devices.ComputerInfo().OSFullName

来自 MSDN:

如果计算机上安装了 Windows Management Instrumentation (WMI),则此属性返回有关操作系统名称的详细信息。否则,此属性将返回与 My.Computer.Info.OSPlatform 属性相同的字符串,后者提供比 WMI 更少的信息。


这是一个错误的解决方案,在我的情况下它只返回字符串“Microsoft”。这是一个错误的解决方案,与My.Computer.Info.OSFullName相同。 - ElektroStudios
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - George
如何知道计算机上是否安装了 WMI? - Kiquenet

4
String subKey = @"SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion";
RegistryKey key = Registry.LocalMachine;
RegistryKey skey = key.OpenSubKey(subKey);
Console.WriteLine("OS Name: {0}", skey.GetValue("ProductName"));

我希望您会发现这个有用


注册表键在64位和32位系统中略有不同,例如在Windows 7的32位注册表中不存在Wow6432Node。 - Scott
1
在 Windows 11 中,ProductName 是“Windows 10”。 - Mister Cook

3
System.OperatingSystem osInfo = System.Environment.OSVersion;

3
它显示的是“Microsoft Windows NT 6.2.9200.0”,这是针对Win 10电脑的。 - SaddamBinSyed
@SaddamBinSyed,请在您的应用程序中添加一个名为 app.manifest 的 XML 文件,并取消注释 assembly\compatibility\application 下 Windows 10 的 <supportedOS> 行。然后您将获得实际的版本字符串,例如 Microsoft Windows NT 10.0.19043.0 - Gabor

2
public int OStype()
    {
        int os = 0;
        IEnumerable<string> list64 = Directory.GetDirectories(Environment.GetEnvironmentVariable("SystemRoot")).Where(s => s.Equals(@"C:\Windows\SysWOW64"));
        IEnumerable<string> list32 = Directory.GetDirectories(Environment.GetEnvironmentVariable("SystemRoot")).Where(s => s.Equals(@"C:\Windows\System32"));
        if (list32.Count() > 0)
        {
            os = 32;
            if (list64.Count() > 0)
                os = 64;
        }
        return os;
    }

1
尽管这不是一个完全使用C#的检测操作系统名称的方法,以下代码适用于我的需求-
public static string GetFriendlyOSName()
    {
        System.Diagnostics.Process cmd = new System.Diagnostics.Process();
        cmd.StartInfo.FileName = "cmd.exe";
        cmd.StartInfo.Arguments = "/C systeminfo | findstr /c:\"OS Name\"";
        cmd.StartInfo.RedirectStandardOutput = true;
        cmd.StartInfo.UseShellExecute = false;
        cmd.StartInfo.CreateNoWindow = true;
        cmd.Start();
        cmd.WaitForExit();
        string output = cmd.StandardOutput.ReadToEnd();
        cmd.Close();
        return output.Split(new[] { ':' }, 2)[1].Trim();
    }

注意:

  1. 此代码仅适用于Windows操作系统。
  2. 该代码仅在Windows 10、11上进行过测试。

“OS Name” 只能在英语操作系统上运行。例如,在德语中,它将是 “Betriebssystemname”。 - KargWare

-1
string text = (string)Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion").GetValue("ProductName");

这段代码将获取完整的操作系统名称,例如 "Windows 8.1 Pro"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接