[C#] - Fast identify the OS Architecture

Discussion in 'Mixed Languages' started by Josh Cell, Oct 23, 2011.

  1. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,106
    120
    #1 Josh Cell, Oct 23, 2011
    Last edited by a moderator: Apr 20, 2017
    Well, this is the code:

    Code:
    //Architecture detector
    
    string arc = null;
    {
                if (IntPtr.Size == 4) arc = "x86";
                if (IntPtr.Size == 8) arc = "x64";
    }
    if (arc == null)
    {
                arc = " Fails decoding the architecture "
    }
    textBox1.Text = arc;
    If you not use the AnyCPU compilation, this is a secure code:

    Code:
    namespace CheckOSBitness
    {
        using System;
        using System.Runtime.InteropServices;
    
        class Validate
        {
            #region Is64BitOperatingSystem (IsWow64Process)
    
            public static bool Is64BitOperatingSystem()
            {
                if (IntPtr.Size == 8)
                {
                    return true;
                }
                else
                {
                    bool flag;
                    return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") &&
                        IsWow64Process(GetCurrentProcess(), out flag)) && flag);
                }
            }
    
            static bool DoesWin32MethodExist(string moduleName, string methodName)
            {
                IntPtr moduleHandle = GetModuleHandle(moduleName);
                if (moduleHandle == IntPtr.Zero)
                {
                    return false;
                }
                return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
            }
    
            [DllImport("kernel32.dll")]
            static extern IntPtr GetCurrentProcess();
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            static extern IntPtr GetModuleHandle(string moduleName);
    
            [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
            static extern IntPtr GetProcAddress(IntPtr hModule,
                [MarshalAs(UnmanagedType.LPStr)]string procName);
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);
    
            #endregion
        }
    }
    Usage:

    Code:
    string arc = "x86";
    if (CheckOSBitness.Validate.Is64BitOperatingSystem()) arc = "x64";
    Well, thanks for Daz for the main code library ;)

    Other ways:

    If you're using the .NET Framework v4 :

     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. BobSheep

    BobSheep MDL Guru

    Apr 19, 2010
    2,326
    1,358
    90
    You should also add that the build must be for Any CPU. If you build on X64 for X86 the size will be 4 not 8.
     
  3. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,106
    120
    #3 Josh Cell, Oct 27, 2011
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Yes, it's true ...

    In this case:

    Code:
    //Architecture detector
    
    string arc = null;
    {
                if (File.Exists(Environment.GetEnvironmentVariable("WINDIR") + "\\SysWOW64\\cmd.exe") arc = "x64";
                else arc = "x86";
    }
    textBox1.Text = arc;
    or

    Code:
    //Architecture detector
    
    string arc = null;
    {
                if (Directory.Exists(Environment.GetEnvironmentVariable("WINDIR") + "\\Sysnative") arc = "x64";
                else arc = "x86";
    }
    textBox1.Text = arc;
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  4. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,238
    150
    #4 CODYQX4, Oct 27, 2011
    Last edited by a moderator: Apr 20, 2017
    Yeah I do the check by cmd.exe, since all the stuff I do that gets redirected is commandline stuff. I use sysnative to force use of 64 bit cmd.exe so that no commands do redirection. Otherwise WOW cmd.exe reg imports get redirected and that's a big no-no when restoring office activation.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,464
    66,504
    300
    #5 Daz, Oct 27, 2011
    Last edited by a moderator: Apr 20, 2017
    Why depend on paths or numbers?
    Code:
    String arc = "x86";
    {
    if (System.Environment.Is64BitOperatingSystem) arc = "x64";
    }
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  6. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,106
    120
    #6 Josh Cell, Oct 28, 2011
    Last edited by a moderator: Apr 20, 2017
    (OP)
    The stuff is an part of .NET v4, you need work with this framework for it :eek:

    More, this is simply and good :)
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,464
    66,504
    300
    #7 Daz, Oct 28, 2011
    Last edited: Oct 28, 2011
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  8. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,106
    120
    #8 Josh Cell, Oct 28, 2011
    Last edited by a moderator: Apr 20, 2017
    (OP)
    In this case, I've modded this function to more simply possible:

    Code:
    namespace CheckOSBitness
    {
        using System;
        using System.Runtime.InteropServices;
    
        class Validate
        {
            #region Is64BitOperatingSystem (IsWow64Process)
    
            public static bool Is64BitOperatingSystem()
            {
                if (IntPtr.Size == 8)
                {
                    return true;
                }
                else
                {
                    bool flag;
                    return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") &&
                        IsWow64Process(GetCurrentProcess(), out flag)) && flag);
                }
            }
    
            static bool DoesWin32MethodExist(string moduleName, string methodName)
            {
                IntPtr moduleHandle = GetModuleHandle(moduleName);
                if (moduleHandle == IntPtr.Zero)
                {
                    return false;
                }
                return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
            }
    
            [DllImport("kernel32.dll")]
            static extern IntPtr GetCurrentProcess();
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            static extern IntPtr GetModuleHandle(string moduleName);
    
            [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
            static extern IntPtr GetProcAddress(IntPtr hModule,
                [MarshalAs(UnmanagedType.LPStr)]string procName);
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);
    
            #endregion
        }
    }
    Usage:

    Code:
    string arc = "x86";
    if (CheckOSBitness.Validate.Is64BitOperatingSystem()) arc = "x64";
    Well, thanks for Daz for the main code library ;)

    .
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,464
    66,504
    300
    For older versions of .NET your second post would do fine for most people, but with the code from MS you shouldn't ever run into problems.

    Glad you found it useful anyway :)
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  10. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,106
    120
    #10 Josh Cell, Oct 28, 2011
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Working directly with WMI

    Code:
    string arc = null;
                ManagementObjectSearcher searcher = 
                        new ManagementObjectSearcher("root\\CIMV2", 
                        "SELECT * FROM Win32_OperatingSystem"); 
    
                    foreach (ManagementObject queryObj in searcher.Get())
                    {
                        arc = queryObj["OSArchitecture"]);
                    }
                catch (ManagementException e)
                {
                    MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
                }
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  11. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,238
    150
    #11 CODYQX4, Oct 28, 2011
    Last edited by a moderator: Apr 20, 2017
    I rely on the path because I kill two birds with one stone, as I have to set that path to force use of 64 bit cmd.exe. I execute process so I have to check for the cmd.exe anyway, but for purely detecting architecture I'd probably use built-in functions.

    I moved OTK to .NET 4 because of RegistryView. Yes I could of used a bunch of interops and rewrote all my registry calls but no way in hell I was changing all those lines to use the functions I'd get from the interops (not enough time/motivation). That and it's nice to be on the latest Framework now.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  12. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,106
    120
    Each version of .NET Framework and Compilers, are thousands of improvements and facilities for the work with this language ...
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  13. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,464
    66,504
    300
    @ CODYQX4
    If you actually needed to access a 64 bit application then that's understandable, I was just simply pointing out that in .NET v4 theres a fast way to identify the OS architecture :)
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  14. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,238
    150
    Yeah theres that built in function I've seen, I think the one you posted is it. .NET 4 added a lot of stuff to make dealing with those architecture differences much easier, as I mentioned the RegistryView thing.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  15. Dermot

    Dermot MDL Novice

    Mar 14, 2011
    2
    0
    0
    #15 Dermot, Jan 14, 2012
    Last edited by a moderator: Apr 20, 2017
    hmm

    this is how i did it...when i needed to.

    Code:
            /// <summary>
            /// Lets see if 32 or 64
            /// </summary>
            #region 32/64 Check
            public static bool Is64BitProcess
            {
                get { return IntPtr.Size == 8; }
            }
    
            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);
            [DllImport("kernel32.dll")]
            public static extern bool Beep(int BeepFreq, int BeepDuration);
    
            public static bool Is64BitOperatingSystem
            {
                get
                {
                    if (Is64BitProcess)
                        return true;
                    bool isWow64;
                    return ModuleContainsFunction("kernel32.dll", "IsWow64Process") && IsWow64Process(GetCurrentProcess(), out isWow64) && isWow64;
                }
            }
            #endregion
    
     
  16. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,106
    120
    #16 Josh Cell, Feb 14, 2012
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Code:
            public static bool Is64BitOperatingSystem()
            {
                if (!Environment.GetFolderPath(Environment.SpecialFolder.SystemX86).ToUpper().Contains("SYSTEM32"))
                    return true;
                return false;
            }
    lol, This simple code will solve all problems :eek::eek::eek:

    Microsoft rules :biggrin:
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  17. QuantumBug

    QuantumBug MDL Developer

    Mar 7, 2012
    1,485
    1,321
    60
  18. PAYMYRENT

    PAYMYRENT MDL Developer

    Jul 28, 2009
    1,462
    419
    60
    #18 PAYMYRENT, Apr 5, 2013
    Last edited by a moderator: Apr 20, 2017
    even better

    Enviroment.Is64Bit whatever blah blah

    Ill post the vb code for it in here

    Code:
    Public Class x64Detection
        'VB.NET Code Conversion from .net 4.5 x86 mscorlib works for older versions as well
        ''' <summary>Determines whether the current operating system is a 64-bit operating system.</summary>
        ''' <returns>true if the operating system is 64-bit; otherwise, false.</returns>
        Public Shared ReadOnly Property Is64BitOperatingSystem As Boolean
            Get
                Dim flag As Boolean = False
                If (DoesWin32MethodExist("kernel32.dll", "IsWow64Process")) OrElse IsWow64Process(GetCurrentProcess(), flag) Then
                    Return True
                Else
                    Return flag
                End If
            End Get
        End Property
    
        Friend Shared Function DoesWin32MethodExist(ByVal moduleName As String, ByVal methodName As String) As Boolean
            Dim moduleHandle As IntPtr = GetModuleHandle(moduleName)
            If (moduleHandle <> IntPtr.Zero) Then
                Dim procAddress As IntPtr = GetProcAddress(moduleHandle, methodName)
                Return procAddress <> IntPtr.Zero
            Else
                Return False
            End If
        End Function
    
        <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
        Friend Shared Function GetCurrentProcess() As IntPtr
        End Function
    
        <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
        Private Shared Function GetModuleHandle(ByVal moduleName As String) As IntPtr
        End Function
    
        <DllImport("kernel32.dll", CharSet:=CharSet.Ansi)> _
        Private Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal methodName As String) As IntPtr
        End Function
    
        <DllImport("kernel32.dll", CharSet:=CharSet.None)> _
        Friend Shared Function IsWow64Process(ByVal hSourceProcessHandle As IntPtr, ByRef isWow64 As Boolean) As Boolean
        End Function
    End Class
    all functions here are slightly modified from the .NET 4+ property Is64bitOperatingSystem in .NET 4+

    Works with .NET 2.0 and it should work on all versions
     
  19. Alphawaves

    Alphawaves Super Moderator/Developer
    Staff Member

    Aug 11, 2008
    5,886
    20,283
    180
    #19 Alphawaves, Apr 5, 2013
    Last edited by a moderator: Apr 20, 2017
    Are we still playing get x64, this works for all .NET.. :eek:

    C#
    Code:
     public static bool Is64BitOperatingSystem
            {
                get
                {
                    foreach (ManagementObject obj in new ManagementObjectSearcher("root\\CIMV2", "SELECT AddressWidth FROM Win32_Processor WHERE AddressWidth =64").Get())
                    {
                        return true;
                    }
                    return false;
                }
            }
    Usage:
    Code:
     if (Is64BitOperatingSystem)
                    MessageBox.Show("x64");
                else
                    MessageBox.Show("x86");
    VB:
    Code:
        Public Shared ReadOnly Property Is64BitOperatingSystem As Boolean
            Get
                For Each obj As ManagementObject In New ManagementObjectSearcher("root\CIMV2", "SELECT AddressWidth FROM Win32_Processor WHERE AddressWidth =64").Get()
                    Return True
                Next
                Return False
            End Get
        End Property
    Usage:
    Code:
        If Is64BitOperatingSystem Then
                MessageBox.Show("x64")
            Else
                MessageBox.Show("x86")
            End If
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  20. PAYMYRENT

    PAYMYRENT MDL Developer

    Jul 28, 2009
    1,462
    419
    60
    That method falls under what I now now days WMI or p\invoke lol for me p]invoke is slightly faster