2015-11-18 78 views
2

在Windows中,猜測當前32位進程是在32位還是64位體系結構上運行的官方方式(在WOW64上運行或不運行)是調用IsWow64Process kernel32.dll中的函數,看看它是否存在(據我瞭解文檔)。確定當前進程是否在WOW64中運行或不在執行

在圍棋,我們可以調用的DLL文件導出與syscall包的功能,所以這裏是我的嘗試:

package main 

import (
    "fmt" 
    "os" 
    "syscall" 
) 

func main() { 
    dll, err := syscall.LoadDLL("kernel32.dll") 
    if err != nil { 
     fmt.Println(err) 
    } 
    defer dll.Release() 
    proc, err := dll.FindProc("IsWow64Process") 
    if err != nil { 
     fmt.Println("Proc not found") // not a WOW64 so a 32 bit system? 
     fmt.Println(err) 
    } 
    fmt.Printf("%v\n", proc) 

    var handle uintptr = uintptr(os.Getpid()) 

    var result uintptr 
    v, x, y := proc.Call(handle, result) 

    fmt.Printf("%v %v %v\n", v, x, y) 
    fmt.Printf("%v\n", result) 
} 

不幸的是,有或沒有WOW64系統測試顯示相同的標準輸出:

&{0x10ada110 IsWow64Process 2088961457} 
0 7 The handle is invalid. 
0 

我該怎麼做?如何實現測試以確定我們的32位Go程序是在64位CPU(WOW64)上還是在真正的32位Windows上的仿真32位上運行?

+1

你完全知道你的代碼基本上測試你的Go代碼是否運行在WOW64仿真上,而不是操作系統是否是32位的arch?要回答*所述的問題*,您應該調用['kernel32!GetNativeSystemInfo()'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724340)並檢查它返回的體系結構。無論您是在32位操作系統上運行32位Go流程,還是在64位操作系統上運行64位Go流程或在64位操作系統上運行32位Go流程,該值都是相同的。 – kostix

+0

感謝您的評論和澄清@kostix。事實上你是對的,我被我認爲是一個32位編譯的Go可執行文件的事實所左右。我是否應該編輯我的問題以反映我想要猜測我們是否在WOW64上運行,然後用Go中的GetNativeSystemInfo函數重新提出一個新問題? [它看起來像是處理這種情況的stackoverflow方式](http://meta.stackoverflow.com/q/283​​408/2583075)。 – Lomanic

+0

編輯問題以反映最終提問和回答的內容,請看@kostix評論。 – Lomanic

回答

4

我相信問題是你的proc.Call上的句柄參數。 IsWow64Process的預期參數是一個HANDLE,與pid不同。這就是爲什麼它表明句柄無效。

以下SO問題How to get process handle from process id表示您需要調用OpenProcess傳遞給pid並返回句柄。

編輯:GetCurrentProcess在syscall中定義。所以,我認爲你可以替換Getpid調用與以下:

handle, err := syscall.GetCurrentProcess() 
+0

感謝您的回答。 [Here](https://play.golang.org/p/q6YOUS58pf)是我的代碼。不幸的是,我有一個運行時異常([鏈接](http://pastebin.aquilenet.fr/?11f1a1d75a631c63#xEoHdDHc6K56GtJOzlOAUrJ7qYpC6DjJI+Vv1DN94eg=)),而運行它,我無法診斷。它發生在proc.Call()行。看起來它不喜歡影響'result' var? – Lomanic

2

OK,所以這裏是一個工作代碼:

package main 

import (
    "syscall" 
    "fmt" 
    "unsafe" 
) 
func main() { 
    dll, err := syscall.LoadDLL("kernel32.dll") 
    if err != nil { 
     fmt.Println("Can't load kernel32") 
     fmt.Println(err) 
    } 
    defer dll.Release() 
    proc, err := dll.FindProc("IsWow64Process") 
    if err != nil { 
     fmt.Println("Proc not found") 
     fmt.Println(err) 
    } 
    fmt.Printf("%v\n",proc) 

    handle, err := syscall.GetCurrentProcess() 
    if err != nil { 
     fmt.Println("Handle not found") 
     fmt.Println(err) 
    } 
    fmt.Printf("%v\n",handle) 

    var result bool 

    v, x, y := proc.Call(uintptr(handle), uintptr(unsafe.Pointer(&result))) 

    fmt.Printf("%v %v %v\n",v,x,y) 
    fmt.Printf("%v\n",result) 
} 

result VAR將是一個爲WOW64系統真假32位系統。

相關問題