|
Great piece of code!
I've slightly updated it to now cater for Windows 8 / Windows 8.1. Even though the original code does support Windows 8, it couldn't differentiate between Win 8 and Win 8.1 as the code hasn't been updated.
The second issue is Windows 8.1 has a version of v6.3, but .Net Framework can still report v6.2 on Windows 8.1 ()[^]) if the application hasn't been manifested for Windows 8.1 - meaning any of these types of approaches of interrogating version numbers could still report an incorrect Windows version - i.e. it'll report Windows 8.1 as Windows 8.
To overcome this flaw, if the MajorVersion equals 6, I than check the registry to get the exact version from the registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion
This ensures an exact version number so I can then report the correct Windows version.
Updated code if anyone is interested:
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace SQLite_Installer
{
public static class OSInfo
{
#region ENUMS
public enum SoftwareArchitecture
{
Unknown = 0,
Bit32 = 1,
Bit64 = 2
}
public enum ProcessorArchitecture
{
Unknown = 0,
Bit32 = 1,
Bit64 = 2,
Itanium64 = 3
}
#endregion ENUMS
#region DELEGATE DECLARATION
private delegate bool IsWow64ProcessDelegate([In] IntPtr handle, [Out] out bool isWow64Process);
#endregion DELEGATE DECLARATION
#region BITS
static public SoftwareArchitecture ProgramBits
{
get
{
SoftwareArchitecture pbits = SoftwareArchitecture.Unknown;
System.Collections.IDictionary test = Environment.GetEnvironmentVariables();
switch (IntPtr.Size * 8)
{
case 64:
pbits = SoftwareArchitecture.Bit64;
break;
case 32:
pbits = SoftwareArchitecture.Bit32;
break;
default:
pbits = SoftwareArchitecture.Unknown;
break;
}
return pbits;
}
}
static public SoftwareArchitecture OSBits
{
get
{
SoftwareArchitecture osbits = SoftwareArchitecture.Unknown;
switch (IntPtr.Size * 8)
{
case 64:
osbits = SoftwareArchitecture.Bit64;
break;
case 32:
if (Is32BitProcessOn64BitProcessor())
osbits = SoftwareArchitecture.Bit64;
else
osbits = SoftwareArchitecture.Bit32;
break;
default:
osbits = SoftwareArchitecture.Unknown;
break;
}
return osbits;
}
}
static public ProcessorArchitecture ProcessorBits
{
get
{
ProcessorArchitecture pbits = ProcessorArchitecture.Unknown;
try
{
SYSTEM_INFO l_System_Info = new SYSTEM_INFO();
GetNativeSystemInfo(ref l_System_Info);
switch (l_System_Info.uProcessorInfo.wProcessorArchitecture)
{
case 9:
pbits = ProcessorArchitecture.Bit64;
break;
case 6:
pbits = ProcessorArchitecture.Itanium64;
break;
case 0:
pbits = ProcessorArchitecture.Bit32;
break;
default:
pbits = ProcessorArchitecture.Unknown;
break;
}
}
catch
{
}
return pbits;
}
}
#endregion BITS
#region EDITION
static private string s_Edition;
static public string Edition
{
get
{
if (s_Edition != null)
return s_Edition;
string edition = String.Empty;
OperatingSystem osVersion = Environment.OSVersion;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX));
if (GetVersionEx(ref osVersionInfo))
{
int majorVersion = osVersion.Version.Major;
int minorVersion = osVersion.Version.Minor;
byte productType = osVersionInfo.wProductType;
short suiteMask = osVersionInfo.wSuiteMask;
#region VERSION 4
if (majorVersion == 4)
{
if (productType == VER_NT_WORKSTATION)
{
edition = "Workstation";
}
else if (productType == VER_NT_SERVER)
{
if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
{
edition = "Enterprise Server";
}
else
{
edition = "Standard Server";
}
}
}
#endregion VERSION 4
#region VERSION 5
else if (majorVersion == 5)
{
if (productType == VER_NT_WORKSTATION)
{
if ((suiteMask & VER_SUITE_PERSONAL) != 0)
{
edition = "Home";
}
else
{
if (GetSystemMetrics(86) == 0)
edition = "Professional";
else
edition = "Tablet Edition";
}
}
else if (productType == VER_NT_SERVER)
{
if (minorVersion == 0)
{
if ((suiteMask & VER_SUITE_DATACENTER) != 0)
{
edition = "Datacenter Server";
}
else if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
{
edition = "Advanced Server";
}
else
{
edition = "Server";
}
}
else
{
if ((suiteMask & VER_SUITE_DATACENTER) != 0)
{
edition = "Datacenter";
}
else if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
{
edition = "Enterprise";
}
else if ((suiteMask & VER_SUITE_BLADE) != 0)
{
edition = "Web Edition";
}
else
{
edition = "Standard";
}
}
}
}
#endregion VERSION 5
#region VERSION 6
else if (majorVersion == 6)
{
int ed;
if (GetProductInfo(majorVersion, minorVersion,
osVersionInfo.wServicePackMajor, osVersionInfo.wServicePackMinor,
out ed))
{
switch (ed)
{
case PRODUCT_BUSINESS:
edition = "Business";
break;
case PRODUCT_BUSINESS_N:
edition = "Business N";
break;
case PRODUCT_CLUSTER_SERVER:
edition = "HPC Edition";
break;
case PRODUCT_CLUSTER_SERVER_V:
edition = "HPC Edition without Hyper-V";
break;
case PRODUCT_DATACENTER_SERVER:
edition = "Datacenter Server";
break;
case PRODUCT_DATACENTER_SERVER_CORE:
edition = "Datacenter Server (core installation)";
break;
case PRODUCT_DATACENTER_SERVER_V:
edition = "Datacenter Server without Hyper-V";
break;
case PRODUCT_DATACENTER_SERVER_CORE_V:
edition = "Datacenter Server without Hyper-V (core installation)";
break;
case PRODUCT_EMBEDDED:
edition = "Embedded";
break;
case PRODUCT_ENTERPRISE:
edition = "Enterprise";
break;
case PRODUCT_ENTERPRISE_N:
edition = "Enterprise N";
break;
case PRODUCT_ENTERPRISE_E:
edition = "Enterprise E";
break;
case PRODUCT_ENTERPRISE_SERVER:
edition = "Enterprise Server";
break;
case PRODUCT_ENTERPRISE_SERVER_CORE:
edition = "Enterprise Server (core installation)";
break;
case PRODUCT_ENTERPRISE_SERVER_CORE_V:
edition = "Enterprise Server without Hyper-V (core installation)";
break;
case PRODUCT_ENTERPRISE_SERVER_IA64:
edition = "Enterprise Server for Itanium-based Systems";
break;
case PRODUCT_ENTERPRISE_SERVER_V:
edition = "Enterprise Server without Hyper-V";
break;
case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT:
edition = "Essential Business Server MGMT";
break;
case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL:
edition = "Essential Business Server ADDL";
break;
case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC:
edition = "Essential Business Server MGMTSVC";
break;
case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC:
edition = "Essential Business Server ADDLSVC";
break;
case PRODUCT_HOME_BASIC:
edition = "Home Basic";
break;
case PRODUCT_HOME_BASIC_N:
edition = "Home Basic N";
break;
case PRODUCT_HOME_BASIC_E:
edition = "Home Basic E";
break;
case PRODUCT_HOME_PREMIUM:
edition = "Home Premium";
break;
case PRODUCT_HOME_PREMIUM_N:
edition = "Home Premium N";
break;
case PRODUCT_HOME_PREMIUM_E:
edition = "Home Premium E";
break;
case PRODUCT_HOME_PREMIUM_SERVER:
edition = "Home Premium Server";
break;
case PRODUCT_HYPERV:
edition = "Microsoft Hyper-V Server";
break;
case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
edition = "Windows Essential Business Management Server";
break;
case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
edition = "Windows Essential Business Messaging Server";
break;
case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
edition = "Windows Essential Business Security Server";
break;
case PRODUCT_PROFESSIONAL:
edition = "Professional";
break;
case PRODUCT_PROFESSIONAL_N:
edition = "Professional N";
break;
case PRODUCT_PROFESSIONAL_E:
edition = "Professional E";
break;
case PRODUCT_SB_SOLUTION_SERVER:
edition = "SB Solution Server";
break;
case PRODUCT_SB_SOLUTION_SERVER_EM:
edition = "SB Solution Server EM";
break;
case PRODUCT_SERVER_FOR_SB_SOLUTIONS:
edition = "Server for SB Solutions";
break;
case PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM:
edition = "Server for SB Solutions EM";
break;
case PRODUCT_SERVER_FOR_SMALLBUSINESS:
edition = "Windows Essential Server Solutions";
break;
case PRODUCT_SERVER_FOR_SMALLBUSINESS_V:
edition = "Windows Essential Server Solutions without Hyper-V";
break;
case PRODUCT_SERVER_FOUNDATION:
edition = "Server Foundation";
break;
case PRODUCT_SMALLBUSINESS_SERVER:
edition = "Windows Small Business Server";
break;
case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
edition = "Windows Small Business Server Premium";
break;
case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE:
edition = "Windows Small Business Server Premium (core installation)";
break;
case PRODUCT_SOLUTION_EMBEDDEDSERVER:
edition = "Solution Embedded Server";
break;
case PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE:
edition = "Solution Embedded Server (core installation)";
break;
case PRODUCT_STANDARD_SERVER:
edition = "Standard Server";
break;
case PRODUCT_STANDARD_SERVER_CORE:
edition = "Standard Server (core installation)";
break;
case PRODUCT_STANDARD_SERVER_SOLUTIONS:
edition = "Standard Server Solutions";
break;
case PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE:
edition = "Standard Server Solutions (core installation)";
break;
case PRODUCT_STANDARD_SERVER_CORE_V:
edition = "Standard Server without Hyper-V (core installation)";
break;
case PRODUCT_STANDARD_SERVER_V:
edition = "Standard Server without Hyper-V";
break;
case PRODUCT_STARTER:
edition = "Starter";
break;
case PRODUCT_STARTER_N:
edition = "Starter N";
break;
case PRODUCT_STARTER_E:
edition = "Starter E";
break;
case PRODUCT_STORAGE_ENTERPRISE_SERVER:
edition = "Enterprise Storage Server";
break;
case PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE:
edition = "Enterprise Storage Server (core installation)";
break;
case PRODUCT_STORAGE_EXPRESS_SERVER:
edition = "Express Storage Server";
break;
case PRODUCT_STORAGE_EXPRESS_SERVER_CORE:
edition = "Express Storage Server (core installation)";
break;
case PRODUCT_STORAGE_STANDARD_SERVER:
edition = "Standard Storage Server";
break;
case PRODUCT_STORAGE_STANDARD_SERVER_CORE:
edition = "Standard Storage Server (core installation)";
break;
case PRODUCT_STORAGE_WORKGROUP_SERVER:
edition = "Workgroup Storage Server";
break;
case PRODUCT_STORAGE_WORKGROUP_SERVER_CORE:
edition = "Workgroup Storage Server (core installation)";
break;
case PRODUCT_UNDEFINED:
edition = "Unknown product";
break;
case PRODUCT_ULTIMATE:
edition = "Ultimate";
break;
case PRODUCT_ULTIMATE_N:
edition = "Ultimate N";
break;
case PRODUCT_ULTIMATE_E:
edition = "Ultimate E";
break;
case PRODUCT_WEB_SERVER:
edition = "Web Server";
break;
case PRODUCT_WEB_SERVER_CORE:
edition = "Web Server (core installation)";
break;
}
}
}
#endregion VERSION 6
}
s_Edition = edition;
return edition;
}
}
#endregion EDITION
#region NAME
static private string s_Name;
static public string Name
{
get
{
if (s_Name != null)
return s_Name;
string name = "unknown";
OperatingSystem osVersion = Environment.OSVersion;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX));
if (GetVersionEx(ref osVersionInfo))
{
int majorVersion = osVersion.Version.Major;
int minorVersion = osVersion.Version.Minor;
switch (osVersion.Platform)
{
case PlatformID.Win32S:
name = "Windows 3.1";
break;
case PlatformID.WinCE:
name = "Windows CE";
break;
case PlatformID.Win32Windows:
{
if (majorVersion == 4)
{
string csdVersion = osVersionInfo.szCSDVersion;
switch (minorVersion)
{
case 0:
if (csdVersion == "B" || csdVersion == "C")
name = "Windows 95 OSR2";
else
name = "Windows 95";
break;
case 10:
if (csdVersion == "A")
name = "Windows 98 Second Edition";
else
name = "Windows 98";
break;
case 90:
name = "Windows Me";
break;
}
}
break;
}
case PlatformID.Win32NT:
{
byte productType = osVersionInfo.wProductType;
switch (majorVersion)
{
case 3:
name = "Windows NT 3.51";
break;
case 4:
switch (productType)
{
case 1:
name = "Windows NT 4.0";
break;
case 3:
name = "Windows NT 4.0 Server";
break;
}
break;
case 5:
switch (minorVersion)
{
case 0:
name = "Windows 2000";
break;
case 1:
name = "Windows XP";
break;
case 2:
name = "Windows Server 2003";
break;
}
break;
case 6:
string exactVersion = RegistryRead(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", "");
if (!String.IsNullOrWhiteSpace(exactVersion))
{
string[] split_result = exactVersion.Split('.');
majorVersion = Convert.ToInt32(split_result[0]);
minorVersion = Convert.ToInt32(split_result[1]);
}
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;
case 2:
switch (productType)
{
case 1:
name = "Windows 8";
break;
case 3:
name = "Windows Server 2012";
break;
}
break;
case 3:
switch (productType)
{
case 1:
name = "Windows 8.1";
break;
case 3:
name = "Windows Server 2012 R2";
break;
}
break;
}
break;
}
break;
}
}
}
s_Name = name;
return name;
}
}
#endregion NAME
private static string RegistryRead(string RegistryPath, string Field, string DefaultValue)
{
string rtn = "";
string backSlash = "";
string newRegistryPath = "";
try
{
RegistryKey OurKey = null;
string[] split_result = RegistryPath.Split('\\');
if (split_result.Length > 0)
{
split_result[0] = split_result[0].ToUpper();
if (split_result[0] == "HKEY_CLASSES_ROOT") OurKey = Registry.ClassesRoot;
else if (split_result[0] == "HKEY_CURRENT_USER") OurKey = Registry.CurrentUser;
else if (split_result[0] == "HKEY_LOCAL_MACHINE") OurKey = Registry.LocalMachine;
else if (split_result[0] == "HKEY_USERS") OurKey = Registry.Users;
else if (split_result[0] == "HKEY_CURRENT_CONFIG") OurKey = Registry.CurrentConfig;
if (OurKey != null)
{
for (int i = 1; i < split_result.Length; i++)
{
newRegistryPath += backSlash + split_result[i];
backSlash = "\\";
}
if (newRegistryPath != "")
{
OurKey = OurKey.OpenSubKey(newRegistryPath);
rtn = (string)OurKey.GetValue(Field, DefaultValue);
OurKey.Close();
}
}
}
}
catch { }
return rtn;
}
#region PINVOKE
#region GET
#region PRODUCT INFO
[DllImport("Kernel32.dll")]
internal static extern bool GetProductInfo(
int osMajorVersion,
int osMinorVersion,
int spMajorVersion,
int spMinorVersion,
out int edition);
#endregion PRODUCT INFO
#region VERSION
[DllImport("kernel32.dll")]
private static extern bool GetVersionEx(ref OSVERSIONINFOEX osVersionInfo);
#endregion VERSION
#region SYSTEMMETRICS
[DllImport("user32")]
public static extern int GetSystemMetrics(int nIndex);
#endregion SYSTEMMETRICS
#region SYSTEMINFO
[DllImport("kernel32.dll")]
public static extern void GetSystemInfo([MarshalAs(UnmanagedType.Struct)] ref SYSTEM_INFO lpSystemInfo);
[DllImport("kernel32.dll")]
public static extern void GetNativeSystemInfo([MarshalAs(UnmanagedType.Struct)] ref SYSTEM_INFO lpSystemInfo);
#endregion SYSTEMINFO
#endregion GET
#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
#region SYSTEM_INFO
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_INFO
{
internal _PROCESSOR_INFO_UNION uProcessorInfo;
public uint dwPageSize;
public IntPtr lpMinimumApplicationAddress;
public IntPtr lpMaximumApplicationAddress;
public IntPtr dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public ushort dwProcessorLevel;
public ushort dwProcessorRevision;
}
#endregion SYSTEM_INFO
#region _PROCESSOR_INFO_UNION
[StructLayout(LayoutKind.Explicit)]
public struct _PROCESSOR_INFO_UNION
{
[FieldOffset(0)]
internal uint dwOemId;
[FieldOffset(0)]
internal ushort wProcessorArchitecture;
[FieldOffset(2)]
internal ushort wReserved;
}
#endregion _PROCESSOR_INFO_UNION
#region 64 BIT OS DETECTION
[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr LoadLibrary(string libraryName);
[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);
#endregion 64 BIT OS DETECTION
#region PRODUCT
private const int PRODUCT_UNDEFINED = 0x00000000;
private const int PRODUCT_ULTIMATE = 0x00000001;
private const int PRODUCT_HOME_BASIC = 0x00000002;
private const int PRODUCT_HOME_PREMIUM = 0x00000003;
private const int PRODUCT_ENTERPRISE = 0x00000004;
private const int PRODUCT_HOME_BASIC_N = 0x00000005;
private const int PRODUCT_BUSINESS = 0x00000006;
private const int PRODUCT_STANDARD_SERVER = 0x00000007;
private const int PRODUCT_DATACENTER_SERVER = 0x00000008;
private const int PRODUCT_SMALLBUSINESS_SERVER = 0x00000009;
private const int PRODUCT_ENTERPRISE_SERVER = 0x0000000A;
private const int PRODUCT_STARTER = 0x0000000B;
private const int PRODUCT_DATACENTER_SERVER_CORE = 0x0000000C;
private const int PRODUCT_STANDARD_SERVER_CORE = 0x0000000D;
private const int PRODUCT_ENTERPRISE_SERVER_CORE = 0x0000000E;
private const int PRODUCT_ENTERPRISE_SERVER_IA64 = 0x0000000F;
private const int PRODUCT_BUSINESS_N = 0x00000010;
private const int PRODUCT_WEB_SERVER = 0x00000011;
private const int PRODUCT_CLUSTER_SERVER = 0x00000012;
private const int PRODUCT_HOME_SERVER = 0x00000013;
private const int PRODUCT_STORAGE_EXPRESS_SERVER = 0x00000014;
private const int PRODUCT_STORAGE_STANDARD_SERVER = 0x00000015;
private const int PRODUCT_STORAGE_WORKGROUP_SERVER = 0x00000016;
private const int PRODUCT_STORAGE_ENTERPRISE_SERVER = 0x00000017;
private const int PRODUCT_SERVER_FOR_SMALLBUSINESS = 0x00000018;
private const int PRODUCT_SMALLBUSINESS_SERVER_PREMIUM = 0x00000019;
private const int PRODUCT_HOME_PREMIUM_N = 0x0000001A;
private const int PRODUCT_ENTERPRISE_N = 0x0000001B;
private const int PRODUCT_ULTIMATE_N = 0x0000001C;
private const int PRODUCT_WEB_SERVER_CORE = 0x0000001D;
private const int PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT = 0x0000001E;
private const int PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY = 0x0000001F;
private const int PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING = 0x00000020;
private const int PRODUCT_SERVER_FOUNDATION = 0x00000021;
private const int PRODUCT_HOME_PREMIUM_SERVER = 0x00000022;
private const int PRODUCT_SERVER_FOR_SMALLBUSINESS_V = 0x00000023;
private const int PRODUCT_STANDARD_SERVER_V = 0x00000024;
private const int PRODUCT_DATACENTER_SERVER_V = 0x00000025;
private const int PRODUCT_ENTERPRISE_SERVER_V = 0x00000026;
private const int PRODUCT_DATACENTER_SERVER_CORE_V = 0x00000027;
private const int PRODUCT_STANDARD_SERVER_CORE_V = 0x00000028;
private const int PRODUCT_ENTERPRISE_SERVER_CORE_V = 0x00000029;
private const int PRODUCT_HYPERV = 0x0000002A;
private const int PRODUCT_STORAGE_EXPRESS_SERVER_CORE = 0x0000002B;
private const int PRODUCT_STORAGE_STANDARD_SERVER_CORE = 0x0000002C;
private const int PRODUCT_STORAGE_WORKGROUP_SERVER_CORE = 0x0000002D;
private const int PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE = 0x0000002E;
private const int PRODUCT_STARTER_N = 0x0000002F;
private const int PRODUCT_PROFESSIONAL = 0x00000030;
private const int PRODUCT_PROFESSIONAL_N = 0x00000031;
private const int PRODUCT_SB_SOLUTION_SERVER = 0x00000032;
private const int PRODUCT_SERVER_FOR_SB_SOLUTIONS = 0x00000033;
private const int PRODUCT_STANDARD_SERVER_SOLUTIONS = 0x00000034;
private const int PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE = 0x00000035;
private const int PRODUCT_SB_SOLUTION_SERVER_EM = 0x00000036;
private const int PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM = 0x00000037;
private const int PRODUCT_SOLUTION_EMBEDDEDSERVER = 0x00000038;
private const int PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE = 0x00000039;
private const int PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT = 0x0000003B;
private const int PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL = 0x0000003C;
private const int PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC = 0x0000003D;
private const int PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC = 0x0000003E;
private const int PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE = 0x0000003F;
private const int PRODUCT_CLUSTER_SERVER_V = 0x00000040;
private const int PRODUCT_EMBEDDED = 0x00000041;
private const int PRODUCT_STARTER_E = 0x00000042;
private const int PRODUCT_HOME_BASIC_E = 0x00000043;
private const int PRODUCT_HOME_PREMIUM_E = 0x00000044;
private const int PRODUCT_PROFESSIONAL_E = 0x00000045;
private const int PRODUCT_ENTERPRISE_E = 0x00000046;
private const int PRODUCT_ULTIMATE_E = 0x00000047;
#endregion PRODUCT
#region VERSIONS
private const int VER_NT_WORKSTATION = 1;
private const int VER_NT_DOMAIN_CONTROLLER = 2;
private const int VER_NT_SERVER = 3;
private const int VER_SUITE_SMALLBUSINESS = 1;
private const int VER_SUITE_ENTERPRISE = 2;
private const int VER_SUITE_TERMINAL = 16;
private const int VER_SUITE_DATACENTER = 128;
private const int VER_SUITE_SINGLEUSERTS = 256;
private const int VER_SUITE_PERSONAL = 512;
private const int VER_SUITE_BLADE = 1024;
#endregion VERSIONS
#endregion PINVOKE
#region SERVICE PACK
static public string ServicePack
{
get
{
string servicePack = String.Empty;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX));
if (GetVersionEx(ref osVersionInfo))
{
servicePack = osVersionInfo.szCSDVersion;
}
return servicePack;
}
}
#endregion SERVICE PACK
#region VERSION
#region BUILD
static public int BuildVersion
{
get
{
return Environment.OSVersion.Version.Build;
}
}
#endregion BUILD
#region FULL
#region STRING
static public string VersionString
{
get
{
return Environment.OSVersion.Version.ToString();
}
}
#endregion STRING
#region VERSION
static public Version Version
{
get
{
return Environment.OSVersion.Version;
}
}
#endregion VERSION
#endregion FULL
#region MAJOR
static public int MajorVersion
{
get
{
return Environment.OSVersion.Version.Major;
}
}
#endregion MAJOR
#region MINOR
static public int MinorVersion
{
get
{
return Environment.OSVersion.Version.Minor;
}
}
#endregion MINOR
#region REVISION
static public int RevisionVersion
{
get
{
return Environment.OSVersion.Version.Revision;
}
}
#endregion REVISION
#endregion VERSION
#region 64 BIT OS DETECTION
private static IsWow64ProcessDelegate GetIsWow64ProcessDelegate()
{
IntPtr handle = LoadLibrary("kernel32");
if (handle != IntPtr.Zero)
{
IntPtr fnPtr = GetProcAddress(handle, "IsWow64Process");
if (fnPtr != IntPtr.Zero)
{
return (IsWow64ProcessDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)fnPtr, typeof(IsWow64ProcessDelegate));
}
}
return null;
}
private static bool Is32BitProcessOn64BitProcessor()
{
IsWow64ProcessDelegate fnDelegate = GetIsWow64ProcessDelegate();
if (fnDelegate == null)
{
return false;
}
bool isWow64;
bool retVal = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, out isWow64);
if (retVal == false)
{
return false;
}
return isWow64;
}
#endregion 64 BIT OS DETECTION
}
}
...this update does of course assume access to the registry. If access is denied, then it will still perform as originally intended - meaning Windows 8.1 will be reported as Windows 8. Without the registry or a Windows 8.1 manifested application than it's impossible to know the exact version.
Great work Johnny J - hope you approve of the update!
Scott Vickery
|
|
|
|
|
Late, I know, but thanks a lot Scott! You registry workaround seems to work perfectly for Windows 8.1
When it comes to Windows 10, though, I can't get the right version out no matter what (without specifically manifesting it in the app manifest, but I would like it to work even without that). Will try to solve the puzzle anyway, but I wonder why MS has to make it so hard for developers. Why the HE** can't you just query Environment.OSVersion and get the RIGHT OS version?
Anything that is unrelated to elephants is irrelephant Anonymous
- The problem with quotes on the internet is that you can never tell if they're genuine Winston Churchill, 1944
- I'd just like a chance to prove that money can't make me happy. Me, all the time
|
|
|
|
|
Nice Article - lots more information than I had previously found.
You might like to add the following Suite Mask
private const int VER_SUITE_HOME_SERVER = -32768;
|
|
|
|
|
Hi Havoxx
Thanks for the suggestion. I'll add it as soon as I get a chance!
Cheers!
Anything that is unrelated to elephants is irrelephant Anonymous ----- Do not argue with an idiot. He will drag you down to his level and beat you with experience Greg King ----- I always wanted to be somebody, but now I realize I should have been more specific. Lily Tomlin, Actress
|
|
|
|
|
Thanks for posting this code! You may want to update your code as the productType for Server 2012 Datacenter is 2 and not 3. I'm not sure if 3 is for some other version of Server 2012 but 2 is definitely Server 2012 as well.
When I initially ran it on Server 2012 it was coming up as 'unknown' but after adding in the case 2 statement for server 2012 all is working fine now. So it should be updated to:
switch (productType)
{
case 1:
name = "Windows 8";
break;
case 2:
case 3:
name = "Windows Server 2012";
break;
}
Thanks again!
|
|
|
|
|
Great Job! But I think that don't show the correct text in Name Property if S.O. version is Microsoft Windows Server 2003 R2 x64, showing "Microsoft Windows Server 2003", without the "R2" text.
|
|
|
|
|
Note that all information returned by OSVERSIONINFOEX is nonsense if the user has right-cliked your application (EXE) and selected a compatibility mode.
Example:
If your operating system is Windows 7 and the user has chosen to run your application in compatibilty mode with Windows XP, the code above will tell that the operating system is Windows XP although it really is Windows 7 (or 8)! Windows will lie to you.
This makes the whole code useless if you have to know on which operating system you are REALLY running!
Be aware of this caveat!
Elmü
|
|
|
|
|
That is because of the way compatibily mode works.
The MS "Shim" Lies to the call and tells you it is on Windows XP or what ever mode.
That is to handle programs that had version = but not > Xp or fail.
Not sure why you would want to run it in compatability mode in the first place.
Ther best choice would to be Not to allow that program to run in compatibility mode.
Most would not add code to check if somone was trying to run it that way.
|
|
|
|
|
But using Systeminfo command we can perform the same activity
|
|
|
|
|
Sure, if you only need to check for your own sake.
The deal with my code is that you can use it in your programs and get the information programmatically so that you can e.g. enable/disable certain functionality based on what operating system the program is run on.
You can't do that with System Info.
Why can't I be applicable like John? - Me, April 2011 ----- Beidh ceol, caint agus craic againn - Seán Bán Breathnach ----- Da mihi sis crustum Etruscum cum omnibus in eo! ----- Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932
|
|
|
|
|
I've updated the source now and added the version numbers for Windows 6 & Windows Server 2012.
Personally, I don't have access to any systems running the mentioned operating systems, so I haven't actually been able to test it. I'm keeping my fingers crossed that it works.
I haven't found any information about Windows RT, so the code is not able to detect that.
Please note: I've kept the Visual Studio 2008 solution and compiled it for .NET runtime 2.0 to make it usable even for older projects. You can update the solution file and or the framework version yourself and recompile it in a matter of seconds if you need to do that!
Why can't I be applicable like John? - Me, April 2011 ----- Beidh ceol, caint agus craic againn - Seán Bán Breathnach ----- Da mihi sis crustum Etruscum cum omnibus in eo! ----- Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932
|
|
|
|
|
|
Great, so it works for Windows 8, but doesn't seem like it detects any edition. I'll look into that, because there was no info from Microsoft about that being changed.
Is your windows 8 version the Standard Windows 8 or is it Pro/enterprise[^]
Why can't I be applicable like John? - Me, April 2011 ----- Beidh ceol, caint agus craic againn - Seán Bán Breathnach ----- Da mihi sis crustum Etruscum cum omnibus in eo! ----- Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932
|
|
|
|
|
Johnny J. wrote: and added the version numbers for Windows 6 ...
You mean Windows 8 right?
The first step in the acquisition of wisdom is SILENCE, the second is LISTENING, the third MEMORY, the forth, PRACTICE and the fifth is TEACHING others!
|
|
|
|
|
Please could you update this like you promised...
Regards from Austria
Dietrich
|
|
|
|
|
OK, I took time off to fix this, so try to test now...
Why can't I be applicable like John? - Me, April 2011 ----- Beidh ceol, caint agus craic againn - Seán Bán Breathnach ----- Da mihi sis crustum Etruscum cum omnibus in eo! ----- Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932
|
|
|
|
|
I am just wanting to detect if my software is installed on a Windows Server. It looks like in your demo the OSVersionInfo.Name on a Windows Server it showed "Windows Server 2008 R2".
Is this enough to know that it is running on a server? Will any versions of Windows 7 or 8 show "Windows Server" for some reason?
And will Windows 2000, 2003 also show "Windows Server" as the beginning text of OSVersionInfo.Name?
|
|
|
|
|
It's very hard for me to answer the question without knowing WHY you need to check if it's a server or not. Everything is relative, and you could (if you wanted to) use any windows machine as a server.
So if the reason you need to know if you're on a server or not is because you want to make sure that there is some specific feature or program installed, then it would be more accurate to check for the existence of that specific feature/program.
Just because you get the information that the OS is "Windows Server 2008 R2", you can't necessarily be sure that it's a full install, I think...
As for the names of the previous server versions: I wrote the code 2 years ago, and I haven't modified it since, so to be quite honest, I don't remember. But the texts can be found in the source code, so it shouldn't be too hard to find out.
Good luck.
Why can't I be applicable like John? - Me, April 2011 ----- Beidh ceol, caint agus craic againn - Seán Bán Breathnach ----- Da mihi sis crustum Etruscum cum omnibus in eo! ----- Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932
|
|
|
|
|
Hello Johnny and Derek
It seems that you both did not read the MSDN.
The information if it is a server operating system or not can be found in wProductType in OS_VERSION_INFO_EX . If it is VER_NT_WORKSTATION , it is not a server.
------------------
> So if the reason you need to know if you're on a server or not is because you want
> to make sure that there is some specific feature or program installed,
> then it would be more accurate to check for the existence of that specific feature/program.
This is not the point.
> Everything is relative, and you could (if you wanted to)
> use any windows machine as a server.
This statement shows a lack of knowledge.
If you could use ANY Windows operating system as server, why should companies pay more money for a real server??
And why should Microsoft offer such a plentitude of different server types?
The workstation OS are very limited in their server functionality (e.g. limited number of connections, speed,...).
They are crippled by Microsoft with the purpose NOT to be usable as high end servers!
Elmü
modified 14-Jan-13 23:05pm.
|
|
|
|
|
VERY well done!! It is quality work like this that make the Internet such a fabulous tool for developers (like me)!
|
|
|
|
|
Thank you too!
Why can't I be applicable like John? - Me, April 2011 ----- Beidh ceol, caint agus craic againn - Seán Bán Breathnach ----- Da mihi sis crustum Etruscum cum omnibus in eo! ----- Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932
|
|
|
|
|
Hi All,
I am trying to create a folder under CommonAppDataFolder during install. It works fine for my Windows7 x64 computer, but the folder does not get created for WindowsXP x86 computer.
In Windows7 I get a folder "C:\ProgramData\MyCompany\MyProgram"
In Windows XP I would have expected a folder "C:\Documents and Settings\All Users\MyCompany\MyProgram", but that folder does not get created. On both computers I can manually create the folder with the user I am logged into, so I don't think its a permission thing.
In VS Setup Project I create a custom folder using "add special folder" saying that the DefaultLocation is: [CommonAppDataFolder][Manufacturer]\[ProductName], then I set the Property property to "COMMONAPPDATAFOLDER".
Is there something I am missing? Something specific to Windows XP?
|
|
|
|
|
Hi
I'm afraid that I no longer have access to any computers running XP, so I can't really verify that for you.
But to be fair, it really has nothing to do with this code either, so my suggestion is that you try posting your question in the Q&A section. Maybe somebody else has had a similar problem?
Good luck.
Why can't I be applicable like John? - Me, April 2011 ----- Beidh ceol, caint agus craic againn - Seán Bán Breathnach ----- Da mihi sis crustum Etruscum cum omnibus in eo! ----- Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932
|
|
|
|
|
Hi,
I use the codes my web app but i cant understand something..
Upload my project to server, i get same result as Windows Server 2003 for per every user ..
But local fine ..
Pls give me any information about this .. Thank you
|
|
|
|
|
|