如何获得"友好"的操作系统版本名称?

Ste*_*ell 59 .net c# operating-system winforms

我正在寻找一种优雅的方式来获得操作系统版本:"Windows XP Professional Service Pack 1"或"Windows Server 2008 Standard Edition"等.

这样做有一种优雅的方式吗?

我也对处理器架构感兴趣(如x86或x64).

Sea*_*ron 68

您可以使用WMI获取产品名称("Microsoft®WindowsServer®2008Enterprise"):

using System.Management;
var name = (from x in new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem").Get().Cast<ManagementObject>()
                      select x.GetPropertyValue("Caption")).FirstOrDefault();
return name != null ? name.ToString() : "Unknown";
Run Code Online (Sandbox Code Playgroud)

  • 使用`FirstOrDefault`而不是`First`方法,或者由于调用了'first`的空集合,该行将因异常而失败. (5认同)
  • 使用`Cast <T>`代替`OfType <T>`也会产生*略微*更好的性能. (3认同)
  • 当我的软件运行上述代码时,我的一些用户遇到了“UnauthorizedAccessException”异常。知道为什么会这样吗? (3认同)

dom*_*key 27

您应该尽量避免WMI供本地使用.这是非常方便的,但你在性能方面付出了巨大的代价.这很简单:

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

  • @NateS没有受苦.[this](http://www.csharp411.com/wp-content/uploads/2009/01/OSInfo.cs)很痛苦! (5认同)
  • 注意:这只能在本地计算机上按照所写的方式工作。您必须将 `Registry.LocalMachine.OpenSubKey(path)` 更改为 `Registry.OpenRemoteBaseKey(RegistryHive.LocalMachine, computer).OpenSubKey(path);` 以使其成为真正的 WMI 替代品(通常用于连接到远程计算机),并传入 `computer`。您还需要使用`ServiceController sc = new ServiceController("RemoteRegistry", computer); 检查远程注册表服务是否正在运行。if (sc.Status.Equals(ServiceControllerStatus.Running)) { ... // 做你的事情 }` &amp; 如果没有,可以启动它:`sc.Start();` (2认同)

con*_*tor 21

为什么不用Environment.OSVersion?它还会告诉你这是什么操作--Windows,Mac OS X,Unix等.要查明你是在64位还是32位运行,请使用IntPtr.Size- 这将返回4位为32位,8位为64位.

  • 我发现`Environment.OSVersion`是不合适的,除非你有一个app.manafest文件说明支持的操作系统.否则,如果您的应用程序以Windows Vista而不是Windows 10运行,则可能会出现完全错误的操作系统版本. (10认同)
  • 从配置程序的链接:"从Windows 8开始,OSVersion属性为所有Windows平台返回相同的主要和次要版本号.因此,我们不建议您检索此属性的值以确定操作系统版本." (4认同)
  • `Environment.OSVersion`确实为你提供了人机版的hte OS名称.例如,WMI将为您提供*Microsoft Windows 8.1 Pro*,`Environment.OSVersion`给出*Microsoft Windows NT 6.2.9200.0*. (3认同)
  • 如果您正在为 x86 平台编译 .NET 应用程序,即使在 64 位操作系统上运行,IntPtr.Size 将返回 4。更好的解决方案在这里:http://stackoverflow.com/questions/336633/how-to-detect-windows-64-bit-platform-with-net (2认同)

Nik*_*ter 14

尝试:

new ComputerInfo().OSVersion;
Run Code Online (Sandbox Code Playgroud)

输出:

Microsoft Windows 10企业版

注意: 添加引用Microsoft.VisualBasic.Devices;

  • `new ComputerInfo().OSFullName`给出了输出. (4认同)
  • 正如您所期望的那样,"OSVersion"会返回版本,而不是名称.使用`OSFullName`获取名称.[ComputerInfo Class](https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.devices.computerinfo(v = vs.110).aspx) (2认同)

小智 10

对我来说,下面的行可以给我输出: Microsoft Windows 10.0.18362

System.Runtime.InteropServices.RuntimeInformation.OSDescription
Run Code Online (Sandbox Code Playgroud)

它也可用于获取架构等信息 https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation?view=netframework-4.8

特性

FrameworkDescription:返回一个字符串,指示运行应用程序的 .NET 安装的名称。

OSArchitecture:获取当前应用运行的平台架构。

OSDescription:获取描述应用程序运行的操作系统的字符串。

ProcessArchitecture:获取当前运行的应用程序的进程架构。

  • 是一个不错的选择,但至少需要 .net Framework 4.7.1 (2认同)

小智 8

有点晚了,但这就是我做到的。将来可能会帮助某人。

using Microsoft.Win32;

RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion");
        string pathName = (string)registryKey.GetValue("productName");
Run Code Online (Sandbox Code Playgroud)


Orw*_*ile 7

样本输出:

Name = Windows Vista
Edition = Home Premium
Service Pack = Service Pack 1
Version = 6.0.6001.65536
Bits = 64
Run Code Online (Sandbox Code Playgroud)

样本类:

class Program
{
    static void Main( string[] args )
    {
        Console.WriteLine( "Operation System Information" );
        Console.WriteLine( "----------------------------" );
        Console.WriteLine( "Name = {0}", OSInfo.Name );
        Console.WriteLine( "Edition = {0}", OSInfo.Edition );
        Console.WriteLine( "Service Pack = {0}", OSInfo.ServicePack );
        Console.WriteLine( "Version = {0}", OSInfo.VersionString );
        Console.WriteLine( "Bits = {0}", OSInfo.Bits );
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

OSInfo类的源代码:http://www.csharp411.com/determine-windows-version-and-edition-with-c/但是代码中有错误,您需要替换"case 6"语句(就在#endregion NAME之前)这个:

case 6:
    switch (minorVersion)
    {
        case 0:

            switch (productType)
            {
                case 1:
                    name = "Windows Vista";
                    break;
                case 3:
                    name = "Windows Server 2008";
                    break;
            }
            break;
        case 1:
            switch (productType)
            {
                case 1:
                    name = "Windows 7";
                    break;
                case 3:
                    name = "Windows Server 2008 R2";
                    break;
            }
            break;
    }
    break;
Run Code Online (Sandbox Code Playgroud)

如果你想更进一步,看看你的程序是以64位还是32位运行:

public static class Wow
{
    public static bool Is64BitProcess
    {
        get { return IntPtr.Size == 8; }
    }

    public static bool Is64BitOperatingSystem
    {
        get
        {
            // Clearly if this is a 64-bit process we must be on a 64-bit OS.
            if (Is64BitProcess)
                return true;
            // Ok, so we are a 32-bit process, but is the OS 64-bit?
            // If we are running under Wow64 than the OS is 64-bit.
            bool isWow64;
            return ModuleContainsFunction("kernel32.dll", "IsWow64Process") && IsWow64Process(GetCurrentProcess(), out isWow64) && isWow64;
        }
    }

    static bool ModuleContainsFunction(string moduleName, string methodName)
    {
        IntPtr hModule = GetModuleHandle(moduleName);
        if (hModule != IntPtr.Zero)
            return GetProcAddress(hModule, methodName) != IntPtr.Zero;
        return false;
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    extern static bool IsWow64Process(IntPtr hProcess, [MarshalAs(UnmanagedType.Bool)] out bool isWow64);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    extern static IntPtr GetCurrentProcess();
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    extern static IntPtr GetModuleHandle(string moduleName);
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    extern static IntPtr GetProcAddress(IntPtr hModule, string methodName);
}
Run Code Online (Sandbox Code Playgroud)

  • @TheMuffinMan - 也许是因为那是2.5年前写的?随着Windows的新版本问世,您将不得不更新它. (2认同)