检测Windows 2008服务器和Windows 2003服务器在C#

检测Windows 2008服务器和Windows 2003服务器在C#

问题描述:

有人可以帮我修改此代码以支持Windows 2003和Windows 2008服务器? 谢谢检测Windows 2008服务器和Windows 2003服务器在C#

public static string getOSLegacy() 
     { 
      //Get Operating system information. 
      OperatingSystem os = Environment.OSVersion; 
      //Get version information about the os. 
      Version vs = os.Version; 

      //Variable to hold our return value 
      string operatingSystem = ""; 

      if (os.Platform == PlatformID.Win32Windows) 
      { 
       //This is a pre-NT version of Windows 
       switch (vs.Minor) 
       { 
        case 0: 
         operatingSystem = "95"; 
         break; 
        case 10: 
         if (vs.Revision.ToString() == "2222A") 
          operatingSystem = "98SE"; 
         else 
          operatingSystem = "98"; 
         break; 
        case 90: 
         operatingSystem = "Me"; 
         break; 
        default: 
         break; 
       } 
      } 
      else if (os.Platform == PlatformID.Win32NT) 
      { 
       switch (vs.Major) 
       { 
        case 3: 
         operatingSystem = "NT 3.51"; 
         break; 
        case 4: 
         operatingSystem = "NT 4.0"; 
         break; 
        case 5: 
         if (vs.Minor == 0) 
         { 
          operatingSystem = "2000"; 
         } 
         else 
         { 
          operatingSystem = "XP"; 
         } 
         break; 
        case 6: 
         if (vs.Minor == 0) 
         { 
          operatingSystem = "Vista"; 
         } 
         else 
         { 
          operatingSystem = "7"; 
         } 
         break; 
        default: 
         break; 
       } 
      } 

      return operatingSystem; 
     } 

2003是5.2。 2008年是6.1。

此帖包含了缺失的部分:http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/5956c04f-072a-406c-ae6a-cc8b3a207936

编辑:由评论指出这个答案是不完整的。 Slavik's answer和链接的文章是一个更好的方法恕我直言。特别是,wProductType字节(不存在于.NET API中)包含关键信息。

+3

由于Windows 7和Server 2008 R2具有相同版本(6.1),并且Win XP 64位与Windows Server 2003具有相同版本,所以此答案为垃圾。 – Stian 2012-06-21 06:08:41

+1

同意。该答案包含虚假信息(以及链接的代码):它指出Win7为6.2,而Win8为6.2 – Salaros 2013-01-26 18:46:25

在Server 2003的版本返回5.2.3790.131072。 在Server 2008上,版本返回6.0.6002.131072。

(在Windows 7上它是6.1.7600.0)。

HKLM \ SOFTWARE \微软\的Windows NT \ CURRENTVERSION,关键产品名称:

此外,您还可以从注册表中获取完整的操作系统名称。

+0

我的2008年返回6.0,但我没有运行R2。 R2有可能是6.1。 – BillP3rd 2010-08-14 06:36:53

在Win32中,您可以使用OSVERSIONINFOEX的wProductType来确定这一点。这似乎很奇怪,这些信息似乎并不通过.NET。也许这是我找不到的地方。无论如何,依靠版本号来区分服务器和非服务器操作系统,我会感到紧张。

Windows Server 2008 R2与R2不同。 查看详情这里: http://www.codeproject.com/KB/miscctrl/OSVersionInfo.aspx

我的代码来检测R2:

public static bool Win7; 

    [DllImport("kernel32.dll")] 
    private static extern bool GetVersionEx(ref OSVERSIONINFOEX osVersionInfo); 

    #region OSVERSIONINFOEX 
    [StructLayout(LayoutKind.Sequential)] 
    private struct OSVERSIONINFOEX 
    { 
     public int dwOSVersionInfoSize; 
     public int dwMajorVersion; 
     public int dwMinorVersion; 
     public int dwBuildNumber; 
     public int dwPlatformId; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
     public string szCSDVersion; 
     public short wServicePackMajor; 
     public short wServicePackMinor; 
     public short wSuiteMask; 
     public byte wProductType; 
     public byte wReserved; 
    } 
    #endregion OSVERSIONINFOEX 

    static MyMethod() { 

     Version ver = System.Environment.OSVersion.Version; 
     OperatingSystem osVersion = Environment.OSVersion; 
     OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX(); 
     osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX)); 

     GetVersionEx(ref osVersionInfo); 
     byte productType = osVersionInfo.wProductType; 

     if (ver.Major==6 & ver.Minor==1 & productType==1) { 
      Win7=true; 
      } 
     else { 
      Win7=false; 
      } 

     if (ver.Major==6 & ver.Minor==1 & productType==3) 
      Report.Info ("OS is Windows Server 2008 R2"); 
     else //here standart methods can be used... 
      Report.Info ("ver.Major: "+ver.Major.ToString()+"\r\nver.Minor: "+ver.Minor.ToString()+"\r\nproductType: "+productType.ToString()); 

我的方案,我需要我的应用程序,以获取可能的错误,报告和统计数据的计算机信息。

我没有找到解决方案,其中应用程序清单必须添加满意。不幸的是,我在Google上搜索时发现的大部分建议都表明了这一点。

当使用清单时,必须手动添加每个操作系统版本,以便特定操作系统版本能够在运行时自行报告。

换句话说,这成为一种竞争条件:我的应用程序的用户很可能正在使用我的应用程序版本以前的日期正在使用的操作系统。当微软启动新的操作系统版本时,我将不得不立即升级应用程序。我还必须强制用户在更新操作系统的同时升级应用程序。

换句话说,不是很可行。

在浏览选项后,我发现一些引用(与应用程序清单相比,出乎意料的少),而不是建议使用注册表查找。

看看这个图表从MS的问候映射OS版本:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832.aspx

我(砍掉)ComputerInfo类只有WinMajorVersionWinMinorVersionIsServer特性如下:

使用的Microsoft.Win32 ;

namespace Inspection 
{ 
    /// <summary> 
    /// Static class that adds convenient methods for getting information on the running computers basic hardware and os setup. 
    /// </summary> 
    public static class ComputerInfo 
    { 
     /// <summary> 
     ///  Returns the Windows major version number for this computer. 
     /// </summary> 
     public static uint WinMajorVersion 
     { 
      get 
      { 
       dynamic major; 
       // The 'CurrentMajorVersionNumber' string value in the CurrentVersion key is new for Windows 10, 
       // and will most likely (hopefully) be there for some time before MS decides to change this - again... 
       if (TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber", out major)) 
       { 
        return (uint) major; 
       } 

       // When the 'CurrentMajorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' 
       dynamic version; 
       if (!TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version)) 
        return 0; 

       var versionParts = ((string) version).Split('.'); 
       if (versionParts.Length != 2) return 0; 
       uint majorAsUInt; 
       return uint.TryParse(versionParts[0], out majorAsUInt) ? majorAsUInt : 0; 
      } 
     } 

     /// <summary> 
     ///  Returns the Windows minor version number for this computer. 
     /// </summary> 
     public static uint WinMinorVersion 
     { 
      get 
      { 
       dynamic minor; 
       // The 'CurrentMinorVersionNumber' string value in the CurrentVersion key is new for Windows 10, 
       // and will most likely (hopefully) be there for some time before MS decides to change this - again... 
       if (TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber", 
        out minor)) 
       { 
        return (uint) minor; 
       } 

       // When the 'CurrentMinorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' 
       dynamic version; 
       if (!TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version)) 
        return 0; 

       var versionParts = ((string) version).Split('.'); 
       if (versionParts.Length != 2) return 0; 
       uint minorAsUInt; 
       return uint.TryParse(versionParts[1], out minorAsUInt) ? minorAsUInt : 0; 
      } 
     } 

     /// <summary> 
     ///  Returns whether or not the current computer is a server or not. 
     /// </summary> 
     public static uint IsServer 
     { 
      get 
      { 
       dynamic installationType; 
       if (TryGeRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "InstallationType", 
        out installationType)) 
       { 
        return (uint) (installationType.Equals("Client") ? 0 : 1); 
       } 

       return 0; 
      } 
     } 

     private static bool TryGeRegistryKey(string path, string key, out dynamic value) 
     { 
      value = null; 
      try 
      { 
       var rk = Registry.LocalMachine.OpenSubKey(path); 
       if (rk == null) return false; 
       value = rk.GetValue(key); 
       return value != null; 
      } 
      catch 
      { 
       return false; 
      } 
     } 
    } 
} 
+0

您描述的竞争条件正是新行为实施的原因。除非您正在设计系统信息工具,否则操作系统版本是您不需要知道的信息。 – EKW 2016-10-18 19:24:51

+0

@EKW,在我的场景中,我需要“系统信息”方面报告用户版本的许可证报告,统计信息和支持。我同意,虽然提供的信息可能不应该用于(ab)用于控制代码中关于要使用或不使用哪些功能的逻辑。 – Spiralis 2016-10-20 08:54:45