确定当前进程是否在 WOW64 中运行或不在 Go 中
Determining if current process runs in WOW64 or not in Go
使用 Windows,猜测当前 32 位进程在 32 位或 64 位体系结构(是否在 WOW64 上)上是 运行 的官方方法是调用 IsWow64Process 来自 kernel32.dll 的函数,并查看它是否存在(据我了解文档)。
在 Go 中,我们可以使用 syscall 包调用 dll 文件中导出的函数,所以这是我的尝试:
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 位上运行还是在真实的 32 位上运行 Windows?
我认为问题出在您 proc.Call
的 handle 参数上。 IsWow64Process
的预期参数是一个 HANDLE,它与 pid
不同。这就是为什么它指示句柄无效。
下面的 SO 问题 How to get process handle from process id 表示您需要调用 OpenProcess
传递 pid 并且它 returns 句柄。
编辑:GetCurrentProcess 在 syscall 中定义。所以我认为您可以用以下内容替换 Getpid
调用:
handle, err := syscall.GetCurrentProcess()
好的,这是一个有效的代码:
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
变量对于 WOW64 系统为真,对于 32 位系统为假。
您也可以使用golang.org/x/sys/windows
package main
import (
"fmt"
"golang.org/x/sys/windows"
)
func main() {
handle := windows.CurrentProcess()
var isWow64 bool
err := windows.IsWow64Process(handle, &isWow64)
if err != nil {
panic(err)
}
fmt.Println(isWow64)
}
使用 Windows,猜测当前 32 位进程在 32 位或 64 位体系结构(是否在 WOW64 上)上是 运行 的官方方法是调用 IsWow64Process 来自 kernel32.dll 的函数,并查看它是否存在(据我了解文档)。
在 Go 中,我们可以使用 syscall 包调用 dll 文件中导出的函数,所以这是我的尝试:
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 位上运行还是在真实的 32 位上运行 Windows?
我认为问题出在您 proc.Call
的 handle 参数上。 IsWow64Process
的预期参数是一个 HANDLE,它与 pid
不同。这就是为什么它指示句柄无效。
下面的 SO 问题 How to get process handle from process id 表示您需要调用 OpenProcess
传递 pid 并且它 returns 句柄。
编辑:GetCurrentProcess 在 syscall 中定义。所以我认为您可以用以下内容替换 Getpid
调用:
handle, err := syscall.GetCurrentProcess()
好的,这是一个有效的代码:
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
变量对于 WOW64 系统为真,对于 32 位系统为假。
您也可以使用golang.org/x/sys/windows
package main
import (
"fmt"
"golang.org/x/sys/windows"
)
func main() {
handle := windows.CurrentProcess()
var isWow64 bool
err := windows.IsWow64Process(handle, &isWow64)
if err != nil {
panic(err)
}
fmt.Println(isWow64)
}