Nice programing

"친숙한"OS 버전 이름을 얻는 방법은 무엇입니까?

nicepro 2020. 12. 10. 21:07
반응형

"친숙한"OS 버전 이름을 얻는 방법은 무엇입니까?


"Windows XP Professional 서비스 팩 1"또는 "Windows Server 2008 Standard Edition"등과 같은 OS 버전을 얻을 수있는 우아한 방법을 찾고 있습니다.

우아한 방법이 있습니까?

프로세서 아키텍처 (예 : x86 또는 x64)에도 관심이 있습니다.


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

로컬 사용을 위해 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 "";
    }

왜 사용하지 Environment.OSVersion않습니까? 또한 Windows, Mac OS X, Unix 등의 작동 방식을 알려줍니다. 64 비트 또는 32 비트에서 실행 중인지 알아 보려면 다음을 사용하십시오. 32 비트의 경우 IntPtr.Size4 바이트, 64 비트의 경우 8 바이트가 반환됩니다.


시험:

new ComputerInfo().OSVersion;

산출:

Microsoft Windows 10 Enterprise

참고 : 다음에 대한 참조 추가Microsoft.VisualBasic.Devices;


샘플 출력 :

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

주의해야 할 사항은이 정보는 일반적으로 현지화되어 있으며 OS의 언어에 따라 다르게보고된다는 것입니다.

Win32_OperatingSystem 클래스에 대한 WMI 검색 에서 많은 정보를 얻을 수 있습니다.


프로세서 아키텍처 질문은 복잡합니다.

의미합니까 (숫자가 높을수록 참이 되려면 낮은 숫자가 필요합니다) :

  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 process is a 64 bit process (not executing under Wow64 for example)

if you are happy that all 3 must be true then

IntPtr.Size == 8

Indicates that all three are true


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

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)

        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.

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


You can use Visual Basic Devices to get version information.

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

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


Disclosure: After posting this, I realized that I am depending on a Nuget extension method library called Z.ExntensionMethods which contains 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));
}

Faster performance 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));
}

output example:

Windows 7

Windows Server 2008

참고URL : https://stackoverflow.com/questions/577634/how-to-get-the-friendly-os-version-name

반응형