Detect windows 2008 server and windows 2003 server in C#
Can someone help me modify this code to support Windows 2003 and Windows 2008 server? Thanks
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;
}
On Server 2003, Version returns 5.2.3790.131072. On Server 2008, Version returns 6.0.6002.131072.
(On Windows 7 it's 6.1.7600.0).
Also, you can get the full OS name from the registry at:
HKLM\Software\Microsoft\Windows NT\CurrentVersion, key ProductName.
2003 is 5.2. 2008 is 6.1.
This post contains the missing pieces: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/5956c04f-072a-406c-ae6a-cc8b3a207936
Edit: This answer is incomplete as noted by the comments. Slavik's answer and the linked article are a much better approach IMHO. In particular, the wProductType byte (that is not present in the .NET API) contains key information.
Windows Server 2008 R2 is different from not R2. See details here: http://www.codeproject.com/KB/miscctrl/OSVersionInfo.aspx
My code to detect 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());
In Win32 you use the wProductType of the OSVERSIONINFOEX to determine this. It seems strange that this information doesn't seem to be available thru .NET. Perhaps it is somewhere that I haven't found. At any rate I would be nervous about relying on version #'s to distinguish server vs. non-server operating systems.
In my scenario I needed my application to capture computer info for possible bug-reports and statistics.
I did not find the solutions where an application manifest had to be added satisfactory. Most of the suggestions I found while googling this suggested just that, unfortunately.
Thing is, when using a manifest, each OS version has to be added manually to it in order for that particular OS version to be able to report itself at runtime.
In other words, this becomes a race condition: A user of my app may very well be using a version of my app that pre-dates the OS in use. I would have to upgrade the app immediately when a new OS version was launched by Microsoft. I would also have to force the users to upgrade the app at the same time as they updated the OS.
In other words, not very feasible.
After browsing through the options I found some references (surprisingly few compared to the app manifest) that instead suggested using registry lookups.
Check out this chart from MS in regards to mapping to OS releases: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832.aspx
My (chopped down) ComputerInfo
class with only WinMajorVersion
, WinMinorVersion
and IsServer
properties looks like this:
using 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;
}
}
}
}
精彩评论