我需要一个全局系统挂钩,它将拦截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位程序崩溃,这是可以预料的,但不是我需要的行为。
那么,为什么它让我拦截整个图书馆,而不是特定的程序呢?
我该怎么做才能把它弄好并在屏幕出现之前阅读全系统的所有文本?