Click here to Skip to main content
11,413,548 members (70,725 online)
Click here to Skip to main content

Getting Operating System Version Info - Even for Windows 8!

, 20 Nov 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Get the operating system version and edition, updated with Windows 8 & Windows Server 2012
OSVersionInfo

Introduction

I was looking for a way to determine the version of the operating system my program was running under. When I Googled it, I got a lot of code hits, but they all had the same problem: They were not updated for Windows 7. 

Also, all of them had the same two shortcomings:

  1. They didn't include all available Windows editions (especially the absence of "Professional" bothered me as that is the operating system edition I normally use)
  2. I wanted to know if the operating system was 32 bit or 64 bit, and none of the solutions I found correctly determined that. Much more on that later...

Background

I found this article http://www.csharp411.com/determine-windows-version-and-edition-with-c/ and that was in my opinion the best and most updated version. So I decided to simply amend that code and add the things that were missing.

Please note: ALL CREDIT FOR THE ORIGINAL CODE GOES TO "TIMM", THE AUTHOR OF THE ABOVEMENTIONED ARTICLE...

Changes Made By Me

  1. I added "Windows 7" and "Windows Server 2008 R2" to the detection scheme.
  2. I added all the missing Windows editions I could find.
  3. Completely rewrote the 32/64 bit detection code.

Using the Code

The class I came up with is very easy to use. Just include the CS file in your project (or compile it to a DLL for use in your VB project), and query the properties like this:

StringBuilder sb = new StringBuilder(String.Empty);
sb.AppendLine("Operation System Information");
sb.AppendLine("----------------------------");
sb.AppendLine(String.Format("Name = {0}", OSVersionInfo.Name));
sb.AppendLine(String.Format("Edition = {0}", OSVersionInfo.Edition));
if (OSVersionInfo.ServicePack!=string.Empty)
sb.AppendLine(String.Format("Service Pack = {0}", OSVersionInfo.ServicePack));
else
sb.AppendLine("Service Pack = None");
sb.AppendLine(String.Format("Version = {0}", OSVersionInfo.VersionString));
sb.AppendLine(String.Format("ProcessorBits = {0}", OSVersionInfo.ProcessorBits));
sb.AppendLine(String.Format("OSBits = {0}", OSVersionInfo.OSBits));
sb.AppendLine(String.Format("ProgramBits = {0}", OSVersionInfo.ProgramBits));

textBox1.Text = sb.ToString();

Points of Interest

The big problem with this was actually the detection of whether or not your OPERATING SYSTEM is 32 or 64 bits. As mentioned, I found a lot of suggestions to how this could be detected, but none of them worked properly. For those who are interested and for the sake of learning/sharing information, I'll list the different suggestions here:

  1. Using the IntPtr size

    The most popular method seems to be variations on this:

    return IntPtr.Size * 8;

    But this doesn't actually return the Bit architecture of the OS, it returns the bit value for the running program. So for programs running in 32 bit mode on 64 bit Windows, the above code will return 32.

  2. Using the 'PROCESSOR_ARCHITECTURE' Environment variable:
    string pa = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
    return ((String.IsNullOrEmpty(pa) || String.Compare(pa, 0,
        "x86", 0, 3, true) == 0) ? 32 : 64);

    This is actually very misleading, because the result of this is exactly the same as version 1: It doesn't return the PROCESSOR bit architecture as the name says, but the bit architecture of the running program. For programs running in 32 bit mode on 64 bit Windows, the above code will ALSO return 32.

  3. Using PInvoke and GetSystemInfo

    Please note: To keep the article at a reasonable length, I'm not including the Structure declarations and the PInvoke API declarations... They can be found in the source code.

    ProcessorArchitecture pbits = ProcessorArchitecture.Unknown;
    try
    {
    SYSTEM_INFO l_System_Info = new SYSTEM_INFO();
    GetSystemInfo(ref l_System_Info);
    switch (l_System_Info.uProcessorInfo.wProcessorArchitecture)
    {
    case 9: // PROCESSOR_ARCHITECTURE_AMD64
    pbits = ProcessorArchitecture.Bit64;
    break;
    case 6: // PROCESSOR_ARCHITECTURE_IA64
    pbits = ProcessorArchitecture.Itanium64;
    break;
    case 0: // PROCESSOR_ARCHITECTURE_INTEL
    pbits = ProcessorArchitecture.Bit32;
    break;
    default: // PROCESSOR_ARCHITECTURE_UNKNOWN
    pbits = ProcessorArchitecture.Unknown;
    break;
    }
    }
    catch
    {
    Ignore 
    }
    return pbits;

    Once again, I was disappointed. This code - despite the presence of the processor specific flags - ALSO returned the bits of the running program, not the OS and not the processor.

  4. Using PInvoke and GetNativeSystemInfo

    I read somewhere that the above was not to be trusted (as I had already discovered), and that you should use the GetNativeSystemInfo API instead.

    The code is exactly the same as the above, but GetSystemInfo is replaced by GetNativeSystemInfo, and the same in the API declaration.

    NOW I got another result. But alas, it seemed that this API actually returns the bit architecture of the processor itself. And I was interested in the OS bit architecture. You can easily have a 32 bit windows version running on a 64 bit processored machine.

    So I was still not done.

    After A LOT of research, I found the method I decided to use in the class:

  5. A combination of IntPtr.Size and IsWow64Process:
    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;
    }
    }
    
    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;
    }

    If the IntPtr size is 64, then the OS MUST be 64 bits as well because you can't run a 64 bit program on a 32 bit OS.

    If the program is running as 32 bits, then the code checks the process the code runs in to determine if that's 32 or 64 bits.

    If it is 64, then the OS will be 64 bits, but the program is running as 32 bits. And if it's 32 then the OS is also 32 bits.

    In the end, I included most of these methods in the final class lib, because it can be nice to be able to distinguish between the bit architecture of the Program, the OS and the Processor.

History 

  • 2012-11-21 - Version 2.0, Added version numbers for Windows 8 & Windows Server 2012 
  • 2010-04-15 - Version 1.0, Initial release  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Johnny J.
Software Developer (Senior)
Sweden Sweden
Born in Copenhagen, Denmark
Have been living in Paris, France and L.A., The United States
Now live in Stockholm, Sweden

Started programming when I got my first VIC 20, and a few months later on Commodore 64. Those were the days!

Studied programming at the Copenhagen Engineering Academy

Professional console, winforms and webforms programming in Comal, x86 Assembler, Fortran, Pascal, Delphi, Visual Basic 3 through 6, Classic ASP, C# and VB.NET

I now work as Senior .NET developer building Airline Booking Systems, and have a number of projects in various states of progress to work on in the spare time...

PS: The cat on my profile is one of my three cats, Ramses. He's all white, odd-eyed, deaf and definitely the coolest cat there is!

Comments and Discussions

 
QuestionWindows 8.1 and Windows 10 Pin
Member 1680010 at 13-Apr-15 1:18
memberMember 168001013-Apr-15 1:18 
QuestionHow? I'm not a programmer. Pin
Member 10959844 at 21-Jul-14 0:21
memberMember 1095984421-Jul-14 0:21 
AnswerRe: How? I'm not a programmer. Pin
Johnny J. at 21-Jul-14 0:33
professionalJohnny J.21-Jul-14 0:33 
QuestionPerfect!!! Pin
EvrenY at 16-May-14 15:36
memberEvrenY16-May-14 15:36 
AnswerYour Code as VB.NET module Pin
mabuse3000 at 29-Apr-14 6:14
membermabuse300029-Apr-14 6:14 
General...and now updated for Windows 8.1 ! Pin
Member 7861383 at 20-Oct-13 8:56
memberMember 786138320-Oct-13 8:56 
QuestionWindows Home Server Pin
Havoxx at 7-Aug-13 1:14
memberHavoxx7-Aug-13 1:14 
AnswerRe: Windows Home Server Pin
Johnny J. at 10-Aug-13 15:52
professionalJohnny J.10-Aug-13 15:52 
QuestionServer 2012 issue. Pin
rasmuffin1 at 29-May-13 8:34
memberrasmuffin129-May-13 8:34 
BugWindows Server 2003 R2 x64 Error Pin
Member 8558369 at 22-Mar-13 3:33
memberMember 855836922-Mar-13 3:33 
NewsImportant: All is useless in Compatibility Mode Pin
Elmue at 14-Jan-13 17:57
memberElmue14-Jan-13 17:57 
GeneralRe: Important: All is useless in Compatibility Mode Pin
ledtech3 at 24-Aug-13 11:48
memberledtech324-Aug-13 11:48 
QuestionPerfect Pin
nishantenet at 21-Nov-12 9:00
membernishantenet21-Nov-12 9:00 
AnswerRe: Perfect Pin
Johnny J. at 21-Nov-12 20:55
memberJohnny J.21-Nov-12 20:55 
QuestionArticle updated! Pin
Johnny J. at 20-Nov-12 23:47
memberJohnny J.20-Nov-12 23:47 
AnswerRe: Article updated! Pin
dherrmann at 21-Nov-12 0:07
memberdherrmann21-Nov-12 0:07 
GeneralRe: Article updated! Pin
Johnny J. at 21-Nov-12 0:09
memberJohnny J.21-Nov-12 0:09 
AnswerRe: Article updated! Pin
GeekBond at 25-Apr-13 7:35
member GeekBond 25-Apr-13 7:35 
QuestionWindows 8 is on the road!!! Pin
dherrmann at 16-Nov-12 7:41
memberdherrmann16-Nov-12 7:41 
AnswerRe: Windows 8 is on the road!!! Pin
Johnny J. at 20-Nov-12 23:45
memberJohnny J.20-Nov-12 23:45 
QuestionDetect Server Pin
Derek Hart at 5-Oct-12 11:13
memberDerek Hart5-Oct-12 11:13 
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?
AnswerRe: Detect Server Pin
Johnny J. at 7-Oct-12 10:10
memberJohnny J.7-Oct-12 10:10 
GeneralRe: Detect Server [modified] Pin
Elmue at 14-Jan-13 17:42
memberElmue14-Jan-13 17:42 
QuestionThank you! Pin
v_wheeler at 18-Aug-12 18:11
memberv_wheeler18-Aug-12 18:11 
AnswerRe: Thank you! Pin
Johnny J. at 21-Aug-12 0:04
memberJohnny J.21-Aug-12 0:04 
QuestionVS2010 Setup and Deployment Project - CommonAppDataFolder for XP Pin
Member 2694153 at 10-Aug-12 9:58
memberMember 269415310-Aug-12 9:58 
AnswerRe: VS2010 Setup and Deployment Project - CommonAppDataFolder for XP Pin
Johnny J. at 21-Aug-12 0:04
memberJohnny J.21-Aug-12 0:04 
QuestionServer name Pin
4hmeT at 7-Aug-12 5:21
member4hmeT7-Aug-12 5:21 
AnswerRe: Server name Pin
4hmeT at 16-Aug-12 4:30
member4hmeT16-Aug-12 4:30 
AnswerRe: Server name Pin
Johnny J. at 20-Aug-12 23:56
memberJohnny J.20-Aug-12 23:56 
QuestionNot working anymore... Pin
supertimmy at 5-Jul-12 22:11
membersupertimmy5-Jul-12 22:11 
AnswerRe: Not working anymore... Pin
Johnny J. at 5-Jul-12 23:40
memberJohnny J.5-Jul-12 23:40 
News32 / 64 bit Pin
AngloThaiSolutions at 9-May-12 9:17
memberAngloThaiSolutions9-May-12 9:17 
QuestionWindows 8 Pin
jonnyboy82 at 20-Mar-12 22:01
memberjonnyboy8220-Mar-12 22:01 
AnswerRe: Windows 8 Pin
Johnny J. at 5-Jul-12 23:41
memberJohnny J.5-Jul-12 23:41 
AnswerRe: Windows 8 Pin
GeekBond at 25-Apr-13 7:30
member GeekBond 25-Apr-13 7:30 
GeneralMy vote of 5 Pin
Rahul Rajat Singh at 17-Feb-12 23:46
memberRahul Rajat Singh17-Feb-12 23:46 
GeneralMy vote of 5 Pin
Kanasz Robert at 4-Jan-12 5:01
memberKanasz Robert4-Jan-12 5:01 
GeneralMy vote of 5 Pin
ShermansLagoon at 21-Nov-11 1:28
memberShermansLagoon21-Nov-11 1:28 
GeneralMy vote of 5 Pin
TwinLane at 12-Nov-11 15:43
memberTwinLane12-Nov-11 15:43 
GeneralMy vote of 5 [modified] Pin
Ilka Guigova at 24-Oct-11 8:45
memberIlka Guigova24-Oct-11 8:45 
GeneralMy vote of 4 Pin
Prashant Singh Thakur at 12-Jun-11 22:51
memberPrashant Singh Thakur12-Jun-11 22:51 
GeneralGreat article Pin
ausadmin at 29-May-11 14:42
memberausadmin29-May-11 14:42 
GeneralMy vote of 5 Pin
cws2_na at 23-Feb-11 5:39
membercws2_na23-Feb-11 5:39 
GeneralBrilliant article Pin
Dave Midgley at 10-Jan-11 4:36
memberDave Midgley10-Jan-11 4:36 
GeneralMy vote of 5 Pin
daddyoh at 14-Dec-10 11:13
memberdaddyoh14-Dec-10 11:13 
GeneralWindows Home Server Pin
rctaubert at 10-Sep-10 6:37
memberrctaubert10-Sep-10 6:37 
GeneralGreat findings... Pin
The Manoj Kumar at 28-Apr-10 18:20
memberThe Manoj Kumar28-Apr-10 18:20 
Generalcomparison to System.Environment.OSVersion Pin
Andrei Rinea at 23-Apr-10 1:13
memberAndrei Rinea23-Apr-10 1:13 
GeneralRe: comparison to System.Environment.OSVersion Pin
Johnny J. at 23-Apr-10 2:05
memberJohnny J.23-Apr-10 2:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150427.1 | Last Updated 21 Nov 2012
Article Copyright 2010 by Johnny J.
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid