SetWindowsHookEx给出错误126:找不到模块

时间:2018-04-18 11:37:20

标签: python windows ctypes setwindowshookex windowserror

我需要一个全局系统挂钩,它将拦截GDI并从应用程序获取屏幕上的所有文本。 我按照这里的说明这样做: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644960(v=vs.85).aspx#installing_releasing

到目前为止

代码:

import ctypes
import atexit
import time
import sys
from ctypes import wintypes, CFUNCTYPE, POINTER, c_int, c_uint, c_void_p, windll, pointer, byref, WinError
import win32con
WH_GETMESSAGE = 3
WH_CALLWNDPROC = 4
cmp_func = CFUNCTYPE(c_int, c_int, wintypes.HINSTANCE, POINTER(c_void_p))
gdi_dll = getattr(ctypes.cdll, 'Gdi32')
SetWindowsHookExA = ctypes.windll.user32.SetWindowsHookExA
SetWindowsHookExA.restype = wintypes.HHOOK
SetWindowsHookExA.argtypes = [c_int, cmp_func, wintypes.HINSTANCE, wintypes.DWORD]
UnhookWindowsHookEx = ctypes.windll.user32.UnhookWindowsHookEx
def _callback_pointer(handler):
    """Create and return C-pointer"""
    print('handler=',cmp_func(handler))
    return cmp_func(handler)

def callback(*args, **kwargs):
    print(args, kwargs)
    res = windll.user32.CallNextHookEx(*args, **kwargs)
    print(res)
    return res

hinstDLL = ctypes.windll.LoadLibrary('Gdi32')._handle
print('hinstDLL=', hinstDLL)
ctypes.windll.kernel32.GetProcAddress.restype = c_int
ctypes.windll.kernel32.GetProcAddress.argtypes = [c_int, ctypes.c_char_p]
hkprcSysMsg = ctypes.windll.kernel32.GetProcAddress(hinstDLL, "TextOutA".encode(encoding='ascii'))
if not hkprcSysMsg:
    error = ctypes.windll.kernel32.GetLastError()
    print(WinError(error))
print('hkprcSysMsg=', hkprcSysMsg)
hook = ctypes.windll.user32.SetWindowsHookExA(
    WH_CALLWNDPROC,
    _callback_pointer(callback),
    hkprcSysMsg,
    # hinstDLL,
    0
)
print('hook=',hook)
error = ctypes.windll.kernel32.GetLastError()
print(WinError(error))
if not hook:
    sys.exit()
while True:
    _process_win_msgs() #not included in this question
    time.sleep(0.02)
atexit.register(UnhookWindowsHookEx, hook)

这始终让我

  

错误126:找不到模块。

但是如果我用hkprcSysMsg替换hinstDLL,钩子就会建立起来并且似乎有效,虽然所有这样做都会导致我在运行时触摸的所有32位程序崩溃,这是可以预料的,但不是我需要的行为。 那么,为什么它让我拦截整个图书馆,而不是特定的程序呢? 我该怎么做才能把它弄好并在屏幕出现之前阅读全系统的所有文本?

0 个答案:

没有答案