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

时间:2009-02-23 13:33:02

标签: c# .net winforms operating-system

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

有一种优雅的方式吗?

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

12 个答案:

答案 0 :(得分:64)

您可以使用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";

答案 1 :(得分: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 "";
    }

答案 2 :(得分:21)

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

答案 3 :(得分:10)

<强>尝试:

new ComputerInfo().OSVersion;

输出

  

Microsoft Windows 10企业版

注意: 添加对Microsoft.VisualBasic.Devices;

的引用

答案 4 :(得分:7)

示例输出:

Name = Windows Vista
Edition = Home Premium
Service Pack = Service Pack 1
Version = 6.0.6001.65536
Bits = 64

示例类:

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();
    }
}

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;

如果你想更进一步,看看你的程序是以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);
}

答案 5 :(得分:4)

对我来说,下面这行有效,输出如下: Microsoft Windows 10.0.18362

System.Runtime.InteropServices.RuntimeInformation.OSDescription

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

属性

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

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

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

ProcessArchitecture:获取当前正在运行的应用程序的流程体系结构。

答案 6 :(得分:3)

有一点需要注意的是,这些信息通常是本地化的,并且会根据操作系统的语言进行不同的报告。

您可以从WMI获取大量信息,查找Win32_OperatingSystem

答案 7 :(得分:2)

请注意,处理器架构问题很复杂:

你的意思是(更高的数字要求更低的数字是真的):

  1. CPU能够处理64位(从某种意义上说它支持AMD / intel x64或Itanium)
  2. 操作系统为64位
    • GPR和指针是64位,即XP 64,Vista 64,64位服务器版本或64位操作系统用于单声道
  3. 当前正在执行的进程是64位进程(例如,不在Wow64下执行)
  4. 如果您对所有3必须是真的感到高兴,那么

    IntPtr.Size == 8
    

    表示这三个都是真的

答案 8 :(得分:1)

我知道这不是问题的直接答案,而且也有点迟了,但对于那些只想找到一种方法来确定操作系统是客户端操作系统还是服务器的人来说,有一种方法可以使用以下:(您需要包含System.Management引用)

        using System;
        using System.Management;

        ManagementClass osClass = new ManagementClass("Win32_OperatingSystem");
        foreach (ManagementObject queryObj in osClass.GetInstances())
        {

            foreach (PropertyData prop in queryObj.Properties)
            {

                if (prop.Name == "ProductType")
                {

                    ProdType = int.Parse(prop.Value.ToString());
                }
            }
        }

而变量ProdType是之前初始化的整数。它将包含1到3之间的值,1表示Workstation,2表示域控制器,3表示服务器。

这取自Accessing the properties of Win32_OperatingSystem并稍作改动......

答案 9 :(得分:1)

迟到了,但这就是我做到的。未来可能会帮助某人。

using Microsoft.Win32;

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

答案 10 :(得分:1)

您可以使用Visual Basic设备获取版本信息。

<强>代码:     

using Microsoft.VisualBasic.Devices;

var versionID = new ComputerInfo().OSVersion;//6.1.7601.65536
var versionName = new ComputerInfo().OSFullName;//Microsoft Windows 7 Ultimate
var verionPlatform = new ComputerInfo().OSPlatform;//WinNT

Console.WriteLine(versionID);
Console.WriteLine(versionName);
Console.WriteLine(verionPlatform);

输出

  

6.1.7601.65536

     

Microsoft Windows 10企业版

     

WINNT

注意: 您需要添加对Microsoft.VisualBasic;

的引用

答案 11 :(得分:0)

披露:发布此内容后,我意识到我依赖于一个名为Z.ExntensionMethods的Nuget扩展方法库,其中包含IndexOf()

using Microsoft.VisualBasic.Devices;

string SimpleOSName()
{
    var name = new ComputerInfo().OSFullName;
    var parts = name.Split(' ').ToArray();
    var take = name.Contains("Server")?3:2;
    return string.Join(" ", parts.Skip(parts.IndexOf("Windows")).Take(take));
}

更快的性能using System.Management;

string SimpleOSName()
{
    var name = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem")
        .Get().Cast<ManagementObject>()
        .Select(x => x.GetPropertyValue("Caption").ToString())
        .First();
    var parts = name.Split(' ').ToArray();
    var take = name.Contains("Server")?3:2;
    return string.Join(" ", parts.Skip(parts.IndexOf("Windows")).Take(take));
}

输出示例:

  

Windows 7

     

Windows Server 2008