windows - Kunne ikke finde SetWindowsHookEx procedure i user32.dll

Indlæg af Hanne Mølgaard Plasc

Problem



OS: Windows 10 64bit
Gå version: Gå version go1.7 windows/amd64


Jeg får følgende fejlmeddelelse, når der køres kode. Jeg forsøgte at køre det med administratorer prividge, men stadig ikke arbejde.


Jeg refererede følgende links,


https://github.com/AllenDang/w32[4]


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


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


Min kode her.


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()
}

Bedste reference


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()
}