2009-02-23 1 views
49

Я ищу элегантный способ получить версию ОС, например: «Windows XP Professional Service Pack 1» или «Windows Server 2008 Standard Edition» и т. Д.Как получить «дружественное» имя версии ОС?

Есть ли элегантный способ сделать это?

Меня также интересует архитектура процессора (например, x86 или x64).

+3

Будьте осторожны, я видел много примеров кода для этого, что ломает, когда пользователь не является администратором ... и конечно, много образцов кода, которые также работают для пользователя, не являющегося администратором. Просто будьте осторожны ^^ –

ответ

61

Вы можете использовать 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"; 
+5

Используйте метод FirstOrDefault вместо метода« First », иначе эта строка не будет выполнена с ошибкой. исключение из-за вызова 'First' пустой коллекции. – franza

+3

Использование 'Cast ' вместо 'OfType ' также дает * немного * лучшую производительность. –

+1

Некоторые из моих пользователей получают исключение «UnauthorizedAccessException», когда мое программное обеспечение выполняет именно указанный выше код. Любая идея, почему это может быть? –

3

Осторожно, эта информация обычно локализована и будет сообщаться по-разному в зависимости от языка ОС.

Вы можете получить много информации из WMI ищет в Win32_OperatingSystem класса

+0

WMI, похоже, будет будущим доказательством, так как он возвращает дружественное имя из коробки без преобразования ... Подойдет ближе. Спасибо ... –

2

Обратите внимание, что архитектура процессора вопрос сложен:

вы имеете в виду (выше numers требуют меньшего числа, чтобы быть правдой):

  1. процессор способен для обработки 64-бита (в том смысле, что она поддерживает AMD/Intel x64 или Itanium)
  2. Операционная система 64-битная
    • GPR и указатели 64бит, т.е. XP 64, Vista 64, выпуск сервера с 64 битной или 64-битной ОС для моно
  3. в настоящее время выполнения процесса это 64 битный процесс (не исполняющие под Wow64, например)

, если вы счастливы, что все три должны быть правдой, то

IntPtr.Size == 8 

Указывает, что все три являются действительными

+0

Разве это не так, как 'IntPtr.Size == 8'? –

+0

Я понимаю, что этот вопрос сложный, как вы сказали. Но мне просто интересно, какая версия Framework обрабатывает мой исполняемый файл. Итак, я считаю, что метод IntPtr будет достаточным. –

+0

@ Хосам: Не совсем. IntPtr.Size - это правильная вещь. – configurator

17

Почему бы не использовать Environment.OSVersion? Он также расскажет вам, что это такое - Windows, Mac OS X, Unix и т. Д. Чтобы узнать, работаете ли вы на 64-битной или 32-битной, используйте IntPtr.Size - это вернет 4 байта для 32-битных и 8 байтов для 64-битных.

+2

'Environment.OSVersion' дает вам человеческую версию имени hte OS. Например, где WMI предоставит вам * Microsoft Windows 8.1 Pro *, 'Environment.OSVersion' дает * Microsoft Windows NT 6.2.9200.0 *. –

+6

Я нашел 'Environment.OSVersion' неуместным, если у вас нет файла app.manafest, в котором содержатся поддерживаемые операционные системы. В противном случае вы можете получить совершенно неправильную версию ОС, если, например, приложение работает под управлением Windows Vista вместо Windows 10. –

+1

IntPtr.Size вернет 4, если вы компилируете .NET-приложения для платформы x86, даже если они работают на 64-битной ОС. Лучшее решение можно найти здесь: http://stackoverflow.com/questions/336633/how-to-detect-windows-64-bit-platform-with-net –

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/ Однако в коде есть ошибка, вам нужно будет заменить оператор «случай 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); 
} 
+1

У меня Windows 8.1, но он говорит, что Windows Vista ... Просматривая исходный код, нет даже аргумента case для Windows 7 или 8 ... –

+2

@ TheMuffinMan - Может, потому, что это было написано 2,5 года назад? Вам придется обновить его, когда появятся новые версии окон. – Orwellophile

23

Вы действительно должны стараться избегать использования 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 ""; 
    } 
+0

Если это так просто, почему люди [страдают] (https://msdn.microsoft.com/library/windows/desktop/ms724429%28v=vs.85%29.aspx) так много? – NateS

+1

Это простое, чтобы получить «дружественное» имя операционной системы локального компьютера. Это может усложниться, когда задействованы номера версий ОС, чего не было задано. – domskey

+4

@NateS, который не страдает. [this] (http://www.csharp411.com/wp-content/uploads/2009/01/OSInfo.cs) страдает! – Sophit

1

Я знаю, что нет прямого ответа на вопрос, и это также немного поздно, но для тех, кто только ищет способ, чтобы определить, является ли ОС Клиент OS или сервер есть способ использовать следующее: (вам необходимо включить ссылку 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 обозначает рабочую станцию, 2 для контроллера домена и 3 для сервера.

Это было взято из Accessing the properties of Win32_OperatingSystem и немного изменился ...

1

Немного поздно, но это, как я это сделал. Может помочь кому-то в будущем.

using Microsoft.Win32; 

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

Это было потрясающе. Или используйте это для удаленного компьютера: 'registryKey = Registry.OpenRemoteBaseKey (RegistryHive.LocalMachine, ) .OpenSubKey (« Программное обеспечение \\ Microsoft \\ Windows NT \\ CurrentVersion »); string version = registryKey.GetValue ("productName"). ToString(); ' – vapcguy

+0

Кроме того, для удовлетворения требования OP пакет обновления находится в том же месте, другая строка:' string servicePack = rk.GetValue ("CSDVersion") .ToString(); ' – vapcguy

7

Try:

new ComputerInfo().OSVersion; 

Выход:

Microsoft Windows 10 Enterprise

Примечание: Добавить ссылку на Microsoft.VisualBasic.Devices;

+3

' new ComputerInfo(). OSFullName' дает этот вывод. – andySF

+1

'OSVersion', как и следовало ожидать, возвращает версию, а не имя. Используйте имя 'OSFullName', чтобы получить имя. [Класс ComputerInfo] (https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.devices.computerinfo (v = vs.110) .aspx) – akinuri

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 Enterprise

WinNT

Примечание: Вам нужно будет добавить ссылку на Microsoft.VisualBasic;

Смежные вопросы