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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/577634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:59:47  来源:igfitidea点击:

How to get the "friendly" OS Version Name?

c#.netwinformsoperating-system

提问by Stefan Koell

I am looking for an elegant way to get the OS version like: "Windows XP Professional Service Pack 1" or "Windows Server 2008 Standard Edition" etc.

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

Is there an elegant way of doing that?

有没有一种优雅的方式来做到这一点?

I am also interested in the processor architecture (like x86 or x64).

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

采纳答案by Sean Kearon

You can use WMI to get the product name ("Microsoft? Windows Server? 2008 Enterprise "):

您可以使用 WMI 获取产品名称(“Microsoft?Windows Server?2008 Enterprise”):

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";

回答by JoshBerke

One thing to be careful of is this information is usually localized and will report differently depending on the language of the OS.

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

You can get a lot of info from WMIlook for the Win32_OperatingSystemclass

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

回答by ShuggyCoUk

Note that the processor architecture question is complex:

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

do you mean (higher numers require lower numbers to be true):

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

  1. The CPU is capable for handling 64bit (in the sense that it supports AMD/intel x64 or Itanium)
  2. The Operating system is 64bit
    • GPR and pointers are 64bits, i.e. XP 64, Vista 64, a 64 bit server release or a 64bit OS for mono
  3. The currently executing processis a 64 bit process (not executing under Wow64 for example)
  1. CPU 能够处理 64 位(从它支持 AMD/intel x64 或 Itanium 的意义上说)
  2. 操作系统是64位
    • GPR 和指针是 64 位的,即 XP 64、Vista 64、64 位服务器版本或 64 位单声道操作系统
  3. 当前正在执行的进程是64位进程(例如在Wow64下不执行)

if you are happy that all 3 must be true then

如果您很高兴所有 3 项都为真,那么

IntPtr.Size == 8

Indicates that all three are true

表示这三个都是真的

回答by configurator

Why not use Environment.OSVersion? It will also tell you what operating this is - Windows, Mac OS X, Unix, etc. To find out if you are running in 64bit or 32bit, use IntPtr.Size- this will return 4 bytes for 32bit and 8 bytes for 64bit.

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

回答by Orwellophile

Sample output:

示例输出:

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

Sample class:

示例类:

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

Source code for OSInfo class: http://www.csharp411.com/determine-windows-version-and-edition-with-c/However there is an error in the code, you will need to replace the "case 6" statement (it's just before #endregion NAME) with this:

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;

And if you want to go a step further and see if your program is running in 64 or 32 bit:

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

回答by domskey

You should really try to avoid WMI for local use. It is very convenient but you pay dearly for it in terms of performance. This is quick and simple:

您真的应该尽量避免在本地使用 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 "";
    }

回答by josibu

I know it is no direct answer to the question and it's also a little bit late, but for those who are only looking for a way to determine whether the OS is a Client OS or a server there is a way to use the following: (you need to include the System.Management reference)

我知道这不是问题的直接答案,也有点晚了,但是对于那些只是在寻找确定操作系统是客户端操作系统还是服务器的方法的人来说,有一种方法可以使用以下内容:(您需要包含 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());
                }
            }
        }

while the variable ProdType is an integer that was initialized before. It will contain a value between 1 and 3 while 1 stands for Workstation, 2 for Domain Controller and 3 for a server.

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

This was taken from Accessing the properties of Win32_OperatingSystemand changed a little bit...

这是从访问 Win32_OperatingSystem 的属性中获取的,并稍作更改...

回答by Noah

Little late, but this is how I did it. Might help someone in the future.

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

using Microsoft.Win32;

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

回答by Niklas Peter

Try:

尝试:

new ComputerInfo().OSVersion;

Output:

输出:

Microsoft Windows 10 Enterprise

微软视窗 10 企业版

Note:Add reference to Microsoft.VisualBasic.Devices;

注意:添加参考Microsoft.VisualBasic.Devices;

回答by Suit Boy Apps

You can use Visual Basic Devices to get version information.

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

Code:

代码:

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

Output:

输出:

6.1.7601.65536

Microsoft Windows 10 Enterprise

WinNT

6.1.7601.65536

微软视窗 10 企业版

WinNT

Note:You will need to add a reference to Microsoft.VisualBasic;

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