无法在user32.dll中找到SetWindowsHookEx过程

时间:2017-09-29 06:02:36

标签: windows winapi go setwindowshookex

操作系统:Windows 10 64位 转到版本: go go go7.7 windows / amd64

运行代码时出现以下错误消息。我尝试使用管理员权限来运行它,但仍然无法正常工作。

我引用了以下链接,

https://github.com/AllenDang/w32

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx

panic: Failed to find SetWindowsHookEx procedure in user32.dll: The specified procedure could not be found.
goroutine 1 [running]:
panic(0x4a7980, 0xc04206c3f0)
    C:/Go/src/runtime/panic.go:500 +0x1af
golang.org/x/sys/windows.(*LazyProc).mustFind(0xc04206c240)
    D:/repos/src/golang.org/x/sys/windows/dll_windows.go:286 +0x71
golang.org/x/sys/windows.(*LazyProc).Call(0xc04206c240, 0xc04203e480, 0x4, 0x4, 0xc042036058, 0x0, 0xc04206c360, 0xc04202def8)
    D:/repos/src/golang.org/x/sys/windows/dll_windows.go:307 +0x36
main.SetWindowsHookEx(0xd, 0x4cab20, 0x0, 0xc000000000, 0x4bfe15)
    d:/repos/src/github.com/quchunguang/trygo/demos/demo_windows_hook/main.go:85 +0xac
main.Start()
    d:/repos/src/github.com/quchunguang/trygo/demos/demo_windows_hook/main.go:147 +0x52
main.main()
    d:/repos/src/github.com/quchunguang/trygo/demos/demo_windows_hook/main.go:166 +0x1b
exit status 2
Process exiting with code: 1

我的代码在这里。

package main

import (
    "fmt"
    "syscall"
    //~ "time"
    "unsafe"

    "golang.org/x/sys/windows"
)

// String returns a human-friendly display name of the hotkey
// such as "Hotkey[Id: 1, Alt+Ctrl+O]"
var (
    user32                  = windows.NewLazySystemDLL("user32.dll")
    procSetWindowsHookEx    = user32.NewProc("SetWindowsHookEx")
    procLowLevelKeyboard    = user32.NewProc("LowLevelKeyboardProc")
    procCallNextHookEx      = user32.NewProc("CallNextHookEx")
    procUnhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx")
    procGetMessage          = user32.NewProc("GetMessageW")
    procTranslateMessage    = user32.NewProc("TranslateMessage")
    procDispatchMessage     = user32.NewProc("DispatchMessageW")
    keyboardHook            HHOOK
)

const (
    WH_KEYBOARD_LL = 13
    WH_KEYBOARD    = 2
    WM_KEYDOWN     = 256
    WM_SYSKEYDOWN  = 260
    WM_KEYUP       = 257
    WM_SYSKEYUP    = 261
    WM_KEYFIRST    = 256
    WM_KEYLAST     = 264
    PM_NOREMOVE    = 0x000
    PM_REMOVE      = 0x001
    PM_NOYIELD     = 0x002
    WM_LBUTTONDOWN = 513
    WM_RBUTTONDOWN = 516
    NULL           = 0
)

type (
    DWORD     uint32
    WPARAM    uintptr
    LPARAM    uintptr
    LRESULT   uintptr
    HANDLE    uintptr
    HINSTANCE HANDLE
    HHOOK     HANDLE
    HWND      HANDLE
)

type HOOKPROC func(int, WPARAM, LPARAM) LRESULT

type KBDLLHOOKSTRUCT struct {
    VkCode      DWORD
    ScanCode    DWORD
    Flags       DWORD
    Time        DWORD
    DwExtraInfo uintptr
}

// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805.aspx
type POINT struct {
    X, Y int32
}

// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx
type MSG struct {
    Hwnd    HWND
    Message uint32
    WParam  uintptr
    LParam  uintptr
    Time    uint32
    Pt      POINT
}

func SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK {
    ret, _, _ := procSetWindowsHookEx.Call(
        uintptr(idHook),
        uintptr(syscall.NewCallback(lpfn)),
        uintptr(hMod),
        uintptr(dwThreadId),
    )
    return HHOOK(ret)
}

func CallNextHookEx(hhk HHOOK, nCode int, wParam WPARAM, lParam LPARAM) LRESULT {
    ret, _, _ := procCallNextHookEx.Call(
        uintptr(hhk),
        uintptr(nCode),
        uintptr(wParam),
        uintptr(lParam),
    )
    return LRESULT(ret)
}

func UnhookWindowsHookEx(hhk HHOOK) bool {
    ret, _, _ := procUnhookWindowsHookEx.Call(
        uintptr(hhk),
    )
    return ret != 0
}

func GetMessage(msg *MSG, hwnd HWND, msgFilterMin uint32, msgFilterMax uint32) int {
    ret, _, _ := procGetMessage.Call(
        uintptr(unsafe.Pointer(msg)),
        uintptr(hwnd),
        uintptr(msgFilterMin),
        uintptr(msgFilterMax))
    return int(ret)
}

func TranslateMessage(msg *MSG) bool {
    ret, _, _ := procTranslateMessage.Call(
        uintptr(unsafe.Pointer(msg)))
    return ret != 0
}

func DispatchMessage(msg *MSG) uintptr {
    ret, _, _ := procDispatchMessage.Call(
        uintptr(unsafe.Pointer(msg)))
    return ret
}

func LowLevelKeyboardProc(nCode int, wParam WPARAM, lParam LPARAM) LRESULT {
    ret, _, _ := procLowLevelKeyboard.Call(
        uintptr(nCode),
        uintptr(wParam),
        uintptr(lParam),
    )
    return LRESULT(ret)
}

func Start() {
    // defer user32.Release()
    keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,
        (HOOKPROC)(func(nCode int, wparam WPARAM, lparam LPARAM) LRESULT {
            if nCode == 0 && wparam == WM_KEYDOWN {
                fmt.Println("key pressed:")
                kbdstruct := (*KBDLLHOOKSTRUCT)(unsafe.Pointer(lparam))
                code := byte(kbdstruct.VkCode)
                fmt.Sprintf("%q", code)
            }
            return CallNextHookEx(keyboardHook, nCode, wparam, lparam)
        }), 0, 0)
    var msg MSG
    for GetMessage(&msg, 0, 0, 0) != 0 {

    }
    //~ for {
    //~
    //~ GetMessage(uintptr(unsafe.Pointer(msg)), 0, 0, 0)
    //~ TranslateMessage(msg)
    //~ DispatchMessage(msg)
    //~ // fmt.Println("key pressed:")
    //~
    //~ }

    UnhookWindowsHookEx(keyboardHook)
    keyboardHook = 0
}

func main() {
    Start()
}

1 个答案:

答案 0 :(得分:0)

package main

import (
    "fmt"
    "syscall"
    "unsafe"

    "golang.org/x/sys/windows"
)

// String returns a human-friendly display name of the hotkey
// such as "Hotkey[Id: 1, Alt+Ctrl+O]"
var (
    user32                  = windows.NewLazySystemDLL("user32.dll")
    procSetWindowsHookEx    = user32.NewProc("SetWindowsHookExW")
    procCallNextHookEx      = user32.NewProc("CallNextHookEx")
    procUnhookWindowsHookEx = user32.NewProc("UnhookWindowsHookEx")
    procGetMessage          = user32.NewProc("GetMessageW")
    procTranslateMessage    = user32.NewProc("TranslateMessage")
    procDispatchMessage     = user32.NewProc("DispatchMessageW")
    keyboardHook            HHOOK
)

const (
    WH_KEYBOARD_LL = 13
    WH_KEYBOARD    = 2
    WM_KEYDOWN     = 256
    WM_SYSKEYDOWN  = 260
    WM_KEYUP       = 257
    WM_SYSKEYUP    = 261
    WM_KEYFIRST    = 256
    WM_KEYLAST     = 264
    PM_NOREMOVE    = 0x000
    PM_REMOVE      = 0x001
    PM_NOYIELD     = 0x002
    WM_LBUTTONDOWN = 513
    WM_RBUTTONDOWN = 516
    NULL           = 0
)

type (
    DWORD     uint32
    WPARAM    uintptr
    LPARAM    uintptr
    LRESULT   uintptr
    HANDLE    uintptr
    HINSTANCE HANDLE
    HHOOK     HANDLE
    HWND      HANDLE
)

type HOOKPROC func(int, WPARAM, LPARAM) LRESULT

type KBDLLHOOKSTRUCT struct {
    VkCode      DWORD
    ScanCode    DWORD
    Flags       DWORD
    Time        DWORD
    DwExtraInfo uintptr
}

// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805.aspx
type POINT struct {
    X, Y int32
}

// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx
type MSG struct {
    Hwnd    HWND
    Message uint32
    WParam  uintptr
    LParam  uintptr
    Time    uint32
    Pt      POINT
}

func SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK {
    ret, _, _ := procSetWindowsHookEx.Call(
        uintptr(idHook),
        uintptr(syscall.NewCallback(lpfn)),
        uintptr(hMod),
        uintptr(dwThreadId),
    )
    return HHOOK(ret)
}

func CallNextHookEx(hhk HHOOK, nCode int, wParam WPARAM, lParam LPARAM) LRESULT {
    ret, _, _ := procCallNextHookEx.Call(
        uintptr(hhk),
        uintptr(nCode),
        uintptr(wParam),
        uintptr(lParam),
    )
    return LRESULT(ret)
}

func UnhookWindowsHookEx(hhk HHOOK) bool {
    ret, _, _ := procUnhookWindowsHookEx.Call(
        uintptr(hhk),
    )
    return ret != 0
}

func GetMessage(msg *MSG, hwnd HWND, msgFilterMin uint32, msgFilterMax uint32) int {
    ret, _, _ := procGetMessage.Call(
        uintptr(unsafe.Pointer(msg)),
        uintptr(hwnd),
        uintptr(msgFilterMin),
        uintptr(msgFilterMax))
    return int(ret)
}

func TranslateMessage(msg *MSG) bool {
    ret, _, _ := procTranslateMessage.Call(
        uintptr(unsafe.Pointer(msg)))
    return ret != 0
}

func DispatchMessage(msg *MSG) uintptr {
    ret, _, _ := procDispatchMessage.Call(
        uintptr(unsafe.Pointer(msg)))
    return ret
}

func Start() {
    // defer user32.Release()
    keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,
        (HOOKPROC)(func(nCode int, wparam WPARAM, lparam LPARAM) LRESULT {
            if nCode == 0 && wparam == WM_KEYDOWN {
                fmt.Println("key pressed:")
                kbdstruct := (*KBDLLHOOKSTRUCT)(unsafe.Pointer(lparam))
                code := rune(kbdstruct.VkCode)
                fmt.Printf("%q", code)
            }
            return CallNextHookEx(keyboardHook, nCode, wparam, lparam)
        }), 0, 0)
    var msg MSG
    for GetMessage(&msg, 0, 0, 0) != 0 {
        // TranslateMessage(msg)
        // DispatchMessage(msg)
    }

    UnhookWindowsHookEx(keyboardHook)
    keyboardHook = 0
}

func main() {
    Start()
}