Results 1 to 15 of 15

Thread: get process exe is x64 or x86

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    get process exe is x64 or x86

    Code:
    dim s as string
    s=Environ("PROCESSOR_ARCHITECTURE")
    if S="x86" THEN
    MSGBOX "32BIT"
    ELSE
    MSGBOX "64BIT"
    END IF
    32bit value="x86"
    64bit vba,value=AMD64

    IT'S UESED FOR VB6,VBA64,TWINBASIC,FREEBASIC
    Last edited by xiaoyao; May 10th, 2023 at 07:07 AM.

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: get process exe is x64 or x86

    VB6
    Code:
    Private Declare Function IsWow64Process Lib "kernel32" (ByVal hProcess As Long, ByRef bIsNotX60 As Boolean) As Boolean
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Const PROCESS_QUERY_INFORMATION As Long = &H400
    Private Const B_X64 As Long = 640 '64位进程ID
    Private Const B_X86 As Long = 2276
    Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwprocessid As Long) As Long
    
    
    Function IsWow64ProcessFromPID(ProcessID As Long) As Boolean
    Dim hProcess As Long
    Dim bIsNotX64 As Boolean
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessID)
    If IsWow64Process(hProcess, bIsNotX64) = False Then
    Err.Raise 22011, , "IsWow64Process 执行失败"""
    End If
    If bIsNotX64 Then
    IsWow64ProcessFromPID = False '32位进程
    Else:
    IsWow64ProcessFromPID = True '64位进程
    End If
    
    End Function
    VBA X64:
    Code:
    Private Declare PtrSafe Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwprocessid As Long) As Long
    
    Private Declare PtrSafe Function IsWow64Process Lib "kernel32" (ByVal hProcess As Long, ByRef bIsNotX60 As Boolean) As Boolean
    Private Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
    Private Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Const PROCESS_QUERY_INFORMATION As Long = &H400
    Private Const B_X64 As Long = 640 '64位进程ID
    Private Const B_X86 As Long = 2276
    
    Sub Main()
    '有用
    'MsgBox IsWow64ProcessFromPID(GetCurrentProcessId)
    End Sub
    Function IsWow64ProcessFromPID(ProcessID As Long) As Boolean
    Dim hProcess As Long
    Dim bIsNotX64 As Boolean
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessID)
    If IsWow64Process(hProcess, bIsNotX64) = False Then
    Err.Raise 22011, , "IsWow64Process 执行失败"""
    End If
    If bIsNotX64 Then
    IsWow64ProcessFromPID = False '32位进程
    Else:
    IsWow64ProcessFromPID = True '64位进程
    End If
    
    End Function

  3. #3
    Lively Member
    Join Date
    Sep 2016
    Posts
    94

    Re: get process exe is x64 or x86

    Stop publishing bits of code that have no interest when they are not documented and very badly translated.
    You must also accept that on this forum the official language is English.

  4. #4
    PowerPoster PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Pontypool, Wales
    Posts
    2,474

    Re: get process exe is x64 or x86

    Quote Originally Posted by xiaoyao View Post
    VB6
    Code:
    Private Declare Function IsWow64Process Lib "kernel32" (ByVal hProcess As Long, ByRef bIsNotX60 As Boolean) As Boolean
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Const PROCESS_QUERY_INFORMATION As Long = &H400
    Private Const B_X64 As Long = 640 '64位进程ID
    Private Const B_X86 As Long = 2276
    Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwprocessid As Long) As Long
    
    
    Function IsWow64ProcessFromPID(ProcessID As Long) As Boolean
    Dim hProcess As Long
    Dim bIsNotX64 As Boolean
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessID)
    If IsWow64Process(hProcess, bIsNotX64) = False Then
    Err.Raise 22011, , "IsWow64Process 执行失败"""
    End If
    If bIsNotX64 Then
    IsWow64ProcessFromPID = False '32位进程
    Else:
    IsWow64ProcessFromPID = True '64位进程
    End If
    
    End Function
    VBA X64:
    Code:
    Private Declare PtrSafe Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwprocessid As Long) As Long
    
    Private Declare PtrSafe Function IsWow64Process Lib "kernel32" (ByVal hProcess As Long, ByRef bIsNotX60 As Boolean) As Boolean
    Private Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
    Private Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Const PROCESS_QUERY_INFORMATION As Long = &H400
    Private Const B_X64 As Long = 640 '64位进程ID
    Private Const B_X86 As Long = 2276
    
    Sub Main()
    '有用
    'MsgBox IsWow64ProcessFromPID(GetCurrentProcessId)
    End Sub
    Function IsWow64ProcessFromPID(ProcessID As Long) As Boolean
    Dim hProcess As Long
    Dim bIsNotX64 As Boolean
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessID)
    If IsWow64Process(hProcess, bIsNotX64) = False Then
    Err.Raise 22011, , "IsWow64Process 执行失败"""
    End If
    If bIsNotX64 Then
    IsWow64ProcessFromPID = False '32位进程
    Else:
    IsWow64ProcessFromPID = True '64位进程
    End If
    
    End Function
    If you are going to post things to CodeBank then please at least make the code decent.

    In those two snippets you have virtually no useful comments, declares and constants that aren't being used, a Main method that only contains a commented out line of code, possibly the weirdest way of naming a variable bIsNotX64 - you are really checking if it is running under WOW, not if it isn't X64, and the end bit is a long winded way of just returning true or false from a boolean variable!

  5. #5
    Lively Member
    Join Date
    May 2021
    Posts
    96

    Re: get process exe is x64 or x86

    Your 64bit API declarations need fixing - it isn't simply a matter of adding PtrSafe to the declaration, you need to adjust the data types to LongPtr/LongLong where appropriate (e.g., handles like hWnd).

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: get process exe is x64 or x86

    Quote Originally Posted by Dan_W View Post
    Your 64bit API declarations need fixing - it isn't simply a matter of adding PtrSafe to the declaration, you need to adjust the data types to LongPtr/LongLong where appropriate (e.g., handles like hWnd).
    It seems that 64-bit programs to change a lot of parameters and structure types, otherwise vb6 source directly generated a 64-bit VB6.exe is convenient. I used ACTIVEX EXE to create an out-of-process COM object, and referenced some other COM DLLS in VBA 64-bit, but I could not directly declare the original object type, only dim a as object, possibly with the same parameter LONG. It's going to be SHORT or INT in 64 bits, so it's not compatible

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: get process exe is x64 or x86

    Quote Originally Posted by PlausiblyDamp View Post
    If you are going to post things to CodeBank then please at least make the code decent.
    possibly the weirdest way of naming a variable bIsNotX64 - you are really checking if it is running under WOW, not if it isn't X64, and the end bit is a long winded way of just returning true or false from a boolean variable!
    Code:
    Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
    Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    
    Private Declare Function IsWow64Process Lib "kernel32" (ByVal hProcess As Long, ByRef bIsNotX60 As Boolean) As Boolean
    'IsWow64Process  
    
    Sub main()
     
    Debug.Print "process is b6bit?" & "Is64bit=" & Is64bitb
    End Sub
    
    Public Function Is64bitb() As Boolean
        Dim handle As Long, Process32_RunOnX64PC As Boolean
        Process32_RunOnX64PC = False
        handle = GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process")
        If handle = 0 Then
                Exit Function
            Else
            IsWow64Process GetCurrentProcess(), Process32_RunOnX64PC
            Debug.Print "Process32_RunOnX64PC=" & Process32_RunOnX64PC
            Is64bitb = Not Process32_RunOnX64PC 
        End If
    End Function
    This code is strange because it returns TRUE in 32-bit VBA 7.1. IsWow64Process means that the current process is running in 32-bit mode on a 64-bit computer.
    The value of Process32_RunOnX64PC is true,
    not Process32_RunOnX64PC should return false, but the result is still true
    I wonder what's wrong with vba7.1 x86( run on x64 it't right)

    This API is not a good solution, there are too many problems, but it is also a way to learn.

    I'll upload more methods when I have time.
    Last edited by xiaoyao; May 10th, 2023 at 08:25 AM.

  8. #8
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: get process exe is x64 or x86

    Quote Originally Posted by xiaoyao View Post
    It seems that 64-bit programs to change a lot of parameters and structure types, otherwise vb6 source directly generated a 64-bit VB6.exe is convenient. I used ACTIVEX EXE to create an out-of-process COM object, and referenced some other COM DLLS in VBA 64-bit, but I could not directly declare the original object type, only dim a as object, possibly with the same parameter LONG. It's going to be SHORT or INT in 64 bits, so it's not compatible
    There are only really 2 things you need to be aware of when switching between 32 and 64 bit.:-

    • The Win32 types LPARAM, WPARAM and LRESULT as well as pointers are 64 bits in a 64 bit process and 32 bits in a 32 bit process.

    • Calling conventions are different. 32 bit applications use the stack to pass parameters but 64 bit applications use a combination of registers and the stack. The stack also has to be aligned a bit different for 64 bit calls.


    There are other concerns like registry virtualization that work differently between 32 and 64 bit processes but these tend to be edge cases more than anything else.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: get process exe is x64 or x86

    I often see a lot of dllhost-exe running, some of which are DOS pipes, some of which I don't know if they are 64-bit calling 32-bit COM objects, or 32-bit EXE calling 64-bit activex DLLS.

    I wonder if there is any way to make a 64-bit VBA call a 32-bit object,COM DLL,OCX via SysWOW64\dllhost.EXE,system32\dllhost.exe or other methods, preferably free of registry reading and writing, no UAC warning

  10. #10
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    5,904

    Re: get process exe is x64 or x86

    What is your goal, what do you want to accomplish??

  11. #11
    Lively Member
    Join Date
    May 2021
    Posts
    96

    Re: get process exe is x64 or x86

    Quote Originally Posted by xiaoyao View Post
    Code:
    Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
    Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    
    Private Declare Function IsWow64Process Lib "kernel32" (ByVal hProcess As Long, ByRef bIsNotX60 As Boolean) As Boolean
    'IsWow64Process  
    
    Sub main()
     
    Debug.Print "process is b6bit?" & "Is64bit=" & Is64bitb
    End Sub
    
    Public Function Is64bitb() As Boolean
        Dim handle As Long, Process32_RunOnX64PC As Boolean
        Process32_RunOnX64PC = False
        handle = GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process")
        If handle = 0 Then
                Exit Function
            Else
            IsWow64Process GetCurrentProcess(), Process32_RunOnX64PC
            Debug.Print "Process32_RunOnX64PC=" & Process32_RunOnX64PC
            Is64bitb = Not Process32_RunOnX64PC 
        End If
    End Function
    This code is strange because it returns TRUE in 32-bit VBA 7.1. IsWow64Process means that the current process is running in 32-bit mode on a 64-bit computer.
    The value of Process32_RunOnX64PC is true,
    not Process32_RunOnX64PC should return false, but the result is still true
    I wonder what's wrong with vba7.1 x86( run on x64 it't right)

    This API is not a good solution, there are too many problems, but it is also a way to learn.

    I'll upload more methods when I have time.
    You may find the following useful: https://www.mrexcel.com/board/thread...6/post-5424462

  12. #12
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,708

    Re: get process exe is x64 or x86

    Quote Originally Posted by Niya View Post
    There are only really 2 things you need to be aware of when switching between 32 and 64 bit.:-

    • The Win32 types LPARAM, WPARAM and LRESULT as well as pointers are 64 bits in a 64 bit process and 32 bits in a 32 bit process.

    • Calling conventions are different. 32 bit applications use the stack to pass parameters but 64 bit applications use a combination of registers and the stack. The stack also has to be aligned a bit different for 64 bit calls.


    There are other concerns like registry virtualization that work differently between 32 and 64 bit processes but these tend to be edge cases more than anything else.
    Also size_t and handles (HANDLE, and a crapton of others... HBITMAP, HICON, HWND, ...). size_t you actually will encounter often, because CopyMemory uses it.

    There's also a few *really* obscure edge cases... like LARGE_INTEGER... which is actually defined as:

    Code:
    typedef union _LARGE_INTEGER {
        struct {
            DWORD LowPart;
            LONG HighPart;
        } DUMMYSTRUCTNAME;
        struct {
            DWORD LowPart;
            LONG HighPart;
        } u;
        LONGLONG QuadPart;
    } LARGE_INTEGER;
    VBx doesn't support LongLong, so everybody has always declared their LARGE_INTEGER with the lowpart/highpart option. However: This makes the compiler see it as 4-byte type, which impacts structure packing.. say you have this:

    Code:
    Type UhOh
        cbSize As Long
        foo As Long
        bar As Long
        foobar As LARGE_INTEGER
    End Type
    VBx will not add any padding to that in x64, because it's all 4 byte types as far as it can see. But some APIs you pass it to will be seeing LARGE_INTEGER as the 8-byte quadpart-only version... so it's expected 4 bytes of padding before foobar, because 8 byte types must appear along an 8-byte interval. If you call such an api, it will best case fail the check of cbSize, worst case crash. And you can't substitue CURRENCY, because underneath, that too is a 2-member 4-byte each UDT to VB, that gets some special handling but not in UDT alignment.

    There's a lot of other UDT alignment issues with x64 conversions... like unions; sometimes a union will have pointers in one version but not in others, and if you had declared it in 32bit without noting that... uh oh.

    It's actually a lot more complicated than people might initially think, I've run into a lot of surprises like these converting some of my projects in x64 in twinBASIC.

  13. #13
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,600

    Re: get process exe is x64 or x86

    Quote Originally Posted by fafalone View Post
    There's also a few *really* obscure edge cases... like LARGE_INTEGER... which is actually defined as:

    Code:
    typedef union _LARGE_INTEGER {
        struct {
            DWORD LowPart;
            LONG HighPart;
        } DUMMYSTRUCTNAME;
        struct {
            DWORD LowPart;
            LONG HighPart;
        } u;
        LONGLONG QuadPart;
    } LARGE_INTEGER;
    VBx doesn't support LongLong, so everybody has always declared their LARGE_INTEGER with the lowpart/highpart option. However: This makes the compiler see it as 4-byte type, which impacts structure packing.. say you have this:

    Code:
    Type UhOh
        cbSize As Long
        foo As Long
        bar As Long
        foobar As LARGE_INTEGER
    End Type
    VBx will not add any padding to that in x64, because it's all 4 byte types as far as it can see. But some APIs you pass it to will be seeing LARGE_INTEGER as the 8-byte quadpart-only version... so it's expected 4 bytes of padding before foobar, because 8 byte types must appear along an 8-byte interval. If you call such an api, it will best case fail the check of cbSize, worst case crash. And you can't substitue CURRENCY, because underneath, that too is a 2-member 4-byte each UDT to VB, that gets some special handling but not in UDT alignment.

    There's a lot of other UDT alignment issues with x64 conversions... like unions; sometimes a union will have pointers in one version but not in others, and if you had declared it in 32bit without noting that... uh oh.

    It's actually a lot more complicated than people might initially think, I've run into a lot of surprises like these converting some of my projects in x64 in twinBASIC.
    Very interesting. I don't think I've ever encountered this particular issue. I often very casually switch between 32 bit and 64 bit compilation in my own .Net applications but now you have me wondering about those that call into the Windows API passing structures. I think I'll run some tests when I wake up later.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  14. #14
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,708

    Re: get process exe is x64 or x86

    .NET has true 8-byte type support, so unless you purposefully declare it incorrectly, it shouldn't come up unless you missed a case of non-default packing.

    One weird one is SHQUERYBININFO for SHQueryRecycleBinW... nearly 1000 lines above it in the SDK header, where you'd never see it, is this:
    Code:
    #if !defined(_WIN64)
    #include <pshpack1.h>
    #endif
    So using a LARGE_INT would actually work on 32bit, but a true 8-byte type wouldn't, which you'd likely never find out about until you said *** enough times to go hit up google/stack overflow/here.

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,749

    Re: get process exe is x64 or x86

    Quote Originally Posted by fafalone View Post
    It's actually a lot more complicated than people might initially think, I've run into a lot of surprises like these converting some of my projects in x64 in twinBASIC.
    I originally had a DLL in PE memory file loading code. Just think of DLLS as resource files like cursor, WAV, You can CALL the API directly without decompressing it to the hard disk. LIKE :Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

    I CAN CHANGE TO :
    jmp GetProcAddress("sqlite.dll","open") to
    PUBLIC Function Sqliteopen (ByVal hObject As Long) As Long
    'This will be overwritten with assembly code
    MSGBOX 1
    MSGBOX 2
    MSGBOX 3
    END FUNCTION

    Code like this started out as VB6, and I converted it to freebasic, which took about an hour.
    Then want to convert to 64 bit standard DLL memory load, took me nearly 2 weeks. Because I do not know where the error has been reported, so every sentence of code from beginning to end debugging, also do not know assembly debugging and other methods.

    So sometimes 32 bit projects to 64 bit, can take a lot of time and cause a lot of mistakes.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width