[VB]OS Architecture via Registry

Discussion in 'Mixed Languages' started by Muerto, Apr 2, 2013.

Thread Status:
Not open for further replies.
  1. Muerto

    Muerto MDL Debugger

    Mar 7, 2012
    1,855
    2,103
    60
    #1 Muerto, Apr 2, 2013
    Last edited by a moderator: Apr 20, 2017
    I've been playing around with a few different ways to generate operating system architecture from Registry data, and I came up with this...

    Code:
        Private arch As String = "32-Bit" 'Default
    
        Private Sub GetArchitecture()
    
            If Registry.LocalMachine.OpenSubKey("Hardware\Description\System\CentralProcessor\0").GetValue("Identifier").ToString.Contains("86") Then
                arch = "32-Bit".ToString
            Else
                If Registry.LocalMachine.OpenSubKey("Hardware\Description\System\CentralProcessor\0").GetValue("Identifier").ToString.Contains("64") Then
                    arch = "64-Bit".ToString
                Else
                    arch = "Could not determine architecture - Instruction size is (" & IntPtr.Size & ")"
                End If
            End If
        End Sub

    But I don't think this is sufficient enough as inside that Registry key is "Intel64 Family 6 Model 42 Stepping 7", so this is only reflecting processor instruction size.

    Is there anywhere in the Registry I can load the OS architecture from?

    I was thinking HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion, BuildLabEx, but I don't know how different this key is depending on OS install versions.

    Regards, The Dev.
     
  2. user_hidden

    user_hidden MDL Expert

    Dec 18, 2007
    1,034
    1,061
    60
    #2 user_hidden, Apr 2, 2013
    Last edited by a moderator: Apr 20, 2017
    Here is a snippet I use in my code:


    Code:
            Dim cpuID As String = _
            My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0", _
            "Identifier", "n/a")
            cpuID = cpuID.Substring(0, cpuID.IndexOf(" "))
    
            If LCase(cpuID).Contains("x86") OrElse LCase(cpuID).Contains("32") Then
    
            [insert you run here]
    
            If LCase(cpuID).Contains("x64") OrElse LCase(cpuID).Contains("64") Then
    
            [insert you run here] 
     
  3. Calistoga

    Calistoga MDL Senior Member

    Jul 25, 2009
    421
    199
    10
    I guess you already know about this, since you specifically asked for a way to do it with the registry. But for anyone who wonders...

    Use Environment.Is64BitOperatingSystem (see MSDN) if your target is .NET 4.0 or newer.

    To stay compatible with older releases of .NET, use the unmanaged GetNativeSystemInfo function (see MSDN) (wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64).

    I have no idea how reliable the information in the registry is, so I can't comment on that.

    :)
     
  4. Muerto

    Muerto MDL Debugger

    Mar 7, 2012
    1,855
    2,103
    60
    #4 Muerto, Apr 2, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    @user_hidden

    I'm trying to get Operating System architecture, not CPU. The function you and I have written is very similar, but it only reads processor architecture, not OS architecture.

    @Calistoga

    My target Framework is .NET 2. I know a few different methods of getting this information, like IntPtr.Size, WMI, etc. I was just messing around and thought there may be some way in the Registry.

    This code works ok,

    Code:
        Private arch As String = "32-Bit" 'Default
    
    #Region "Determine OS Architecture"
    
        Private Sub GenerateArc()
    
            If IntPtr.Size = 4 Then
                arch = "32-Bit".ToString
            Else
                If IntPtr.Size = 8 Then
                    arch = "64-Bit".ToString
                Else
                    arch = "Unknown".ToString
                End If
            End If
    
        End Sub
    
    #End Region
    Regard, The Dev.
     
  5. PAYMYRENT

    PAYMYRENT MDL Developer

    Jul 28, 2009
    1,460
    420
    60
    You havent delt with modded operating systems that much because of releases like the nVidia one or other of the sort registry is not the way to go. source like WMI will\should always return the proper data unless the providers have been modified also
     
  6. Muerto

    Muerto MDL Debugger

    Mar 7, 2012
    1,855
    2,103
    60
    @PMR

    Win32_OperatingSystem (OSArchitecture) it is then, I guess?
     
  7. Muerto

    Muerto MDL Debugger

    Mar 7, 2012
    1,855
    2,103
    60
    #7 Muerto, Apr 2, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Ok, maybe this, works well...

    Code:
        Private arch As String = "32-Bit".ToString 'Default
    
        Private Function GenerateArc() As String
    
            Try
                Dim oWMI As New ManagementObjectSearcher _
                ("root\CIMV2", "SELECT OSArchitecture FROM Win32_OperatingSystem")
                For Each WmiResults As ManagementObject In oWMI.Get()
                    arch = WmiResults.GetPropertyValue("OSArchitecture").ToString
                    If (Not String.IsNullOrEmpty(arch)) Then
                        Exit For
                    End If
                Next
    
            Catch ex As ManagementException
                MessageBox.Show("An error occured in GenerateArc().", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
    
            Return arch
    
        End Function
     
  8. PAYMYRENT

    PAYMYRENT MDL Developer

    Jul 28, 2009
    1,460
    420
    60
    that could work... im not too sure about the p\invoke way but i can test lol
     
  9. Alphawaves

    Alphawaves Super Moderator/Developer
    Staff Member

    Aug 11, 2008
    6,222
    22,280
    210
    #9 Alphawaves, Apr 3, 2013
    Last edited by a moderator: Apr 20, 2017
    Another to your list...
    Code:
    string result = string.Empty;
                foreach (ManagementObject os in new ManagementObjectSearcher("root\\CIMV2", "SELECT AddressWidth FROM Win32_Processor").Get())
                {
                    result = Convert.ToString(os["AddressWidth"]);
                    if (!string.IsNullOrEmpty(result)) 
                    {
                        MessageBox.Show(result);
                    }
                }
    although maybe best to search for file like cmd in syswow64 ?:icecream:
     
  10. Muerto

    Muerto MDL Debugger

    Mar 7, 2012
    1,855
    2,103
    60
    #10 Muerto, Apr 3, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Maybe this is a bit of a long shot, could possibly be edited to work better.

    Code:
        Private arch As String = "32-Bit" ' Default
    
        Private Sub GenerateArc(ByVal loc As String)
    
                If System.IO.Directory.Exists(loc) = True Then
                arch = "64-bit"
            Else
                If System.IO.Directory.Exists(loc) = False Then
                    arch = "32-Bit"
                Else
                    arch = "Could not resolve platform architecture"
                End If
            End If
    
        End Sub
    
        Private Sub btn1_Click(sender As Object, e As EventArgs) Handles Button1.Click
             Call GenerateArc(Environment.GetEnvironmentVariable("windir") & "\SysWOW64")
             MessageBox.Show(arch)
        End Sub
    SysWOW64 only exists in 64 Operating Systems, right? Also, what if the user doesn't have windows installed on C:?

    EDIT:

    Have made it like Alpha said...

    Code:
        Private arch As String = "32-Bit" ' Default
    
        Private Sub GenerateArc(ByVal loc As String)
    
           If System.IO.File.Exists(loc) = True Then
                arch = "64-bit"
            Else
                If System.IO.File.Exists(loc) = False Then
                    arch = "32-Bit"
                Else
                    arch = "Could not resolve platform architecture"
                End If
            End If
    
        End Sub
    
    
    
        Private Sub btn1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Call GenerateArc(Environment.GetEnvironmentVariable("windir") & "\SysWOW64\cmd.exe")
            MessageBox.Show(arch)
        End Sub
    Here is a VB.NET port of Alphawaves code - See #9

    Code:
            Dim result As String = String.Empty
            For Each os As ManagementObject In New ManagementObjectSearcher("root\CIMV2", "SELECT AddressWidth FROM Win32_Processor").Get()
                result = Convert.ToString(os("AddressWidth"))
                If Not String.IsNullOrEmpty(result) Then
                    MessageBox.Show(result)
                End If
            Next
     
  11. Calistoga

    Calistoga MDL Senior Member

    Jul 25, 2009
    421
    199
    10
    I don't think looking for a folder is a very good idea in the long run. The SysWOW64 folder is not guaranteed to have that name in future releases of Windows (remember C:\WINDOWS vs C:\WINNT).
    ;)
     
  12. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,515
    7,170
    120
    For me, the best way to do architecture detection on x86 applications are looking for the Sysnative virtual directory on WOW64 system:

    If you are developing 'AnyCPU' app, you easily can do this checking for the IntPtr size at the memory:

    You also can look for essential files inside the Sysnative dir applying these modifications for prevent invalid detection when the Sysnative directory has been created on a x86 operating system:

    This way is not the best but it works anyway:

    Another ways can be found at: http://forums.mydigitallife.net/threads/29914-C-Fast-identify-the-OS-Architecture
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  13. PAYMYRENT

    PAYMYRENT MDL Developer

    Jul 28, 2009
    1,460
    420
    60
    lol Folders :p

    WMI is probably one of the best ways to get that information ... Its quick and reliable. As was stated in #11 folder names change. And virtual folder can be remapped if you know what you are doing.

    Ive used WMI to get that information for years now. 64-bit return on x64 for a 32-bit compiled application and then use Kernel32.dll to disable FSRedirection :orb:
     
  14. Muerto

    Muerto MDL Debugger

    Mar 7, 2012
    1,855
    2,103
    60
    @PMR - I did end up using WMI in the end. Seems it will be the most fail-safe way. But even if that does fail you can just check IntPtr.Size.

    Hmm, this is kind of a double post. But both are really useful. Mods lock this and I'll place a link in Josh Cells post?

    Regards, The Dev.