2014-10-02 22 views
7

我编写了这段代码来观察keydown运动的事件。这个问题似乎是,当运行此脚本时,某些程序会崩溃这个程序,吐出此错误消息:pythoncom在KeyDown使用时挂在某些应用程序上时崩溃

TypeError: KeyboardSwitch() missing 8 required positional arguments: 'msg', 'vk_ 
code', 'scan_code', 'ascii', 'flags', 'time', 'hwnd', and 'win_name' 

观察到崩溃一些程序:Skype的,崇高的文本2

后很少有试验在调试它,这个问题似乎在最后一行发生,但我似乎无法缩小它的范围。我也搞不懂是由编译器返回KeyboardSwitch()的意思......

我还发现,该方案将返回交替此错误消息

Traceback (most recent call last): 
    File "C:\Python34\lib\site-packages\pyHook\HookManager.py", line 351, in KeyboardSwitch 
    return func(event) 
    File "observe.py", line 6, in OnKeyboardEvent 
    print ('MessageName:',event.MessageName) 
TypeError: an integer is required (got type NoneType) 

的原因是什么,以及如何我是否解决这个问题,特别是因为它只出现在按下的两个按键中的一个中:

import pyHook, pythoncom 

def OnKeyboardEvent(event): 
# Source: http://code.activestate.com/recipes/553270-using-pyhook-to-block-windows-keys/ 
    print ('MessageName:',event.MessageName) 
    print ('Message:',event.Message) 
    print ('Time:',event.Time) 
    print ('Window:',event.Window) 
    print ('WindowName:',event.WindowName) 
    print ('Ascii:', event.Ascii, chr(event.Ascii)) 
    print ('Key:', event.Key) 
    print ('KeyID:', event.KeyID) 
    print ('ScanCode:', event.ScanCode) 
    print ('Extended:', event.Extended) 
    print ('Injected:', event.Injected) 
    print ('Alt', event.Alt) 
    print ('Transition', event.Transition) 
    print ('---') 

hooks_manager = pyHook.HookManager() 
hooks_manager.KeyDown = OnKeyboardEvent 
hooks_manager.HookKeyboard() 
pythoncom.PumpMessages() 

PS作为一名初学者,我对pythoncom的功能并不十分熟悉,在线定义看起来相当模糊。对pythoncom和PumpMessages的功能的解释将不胜感激。

感谢

回答

0

如果只有1每2台印刷机的作品,它是definetely失踪返回值的问题。尝试返回True或False。

6

我认为问题是,当pyHook被Windows回叫时,它所做的第一件事就是获得焦点窗口的窗口名称。

PSTR win_name = NULL; 
... 
// grab the window name if possible 
win_len = GetWindowTextLength(hwnd); 
if(win_len > 0) { 
    win_name = (PSTR) malloc(sizeof(char) * win_len + 1); 
    GetWindowText(hwnd, win_name, win_len + 1); 
} 

所以我觉得这里的问题是,即使GetWindowText没有返回宽字符,它可以从一个ANSI代码返回非ASCII字符。这不会失败,然而,直到我们这样做:

// pass the message on to the Python function 
arglist = Py_BuildValue("(iiiiiiiz)", wParam, kbd->vkCode, kbd->scanCode, ascii, 
         kbd->flags, kbd->time, hwnd, win_name); 

这里,因为在格式字符串中的z,在win_name可变数据被转换为Unicode strPy_BuildValue假设它是ASCII 。但它不是:所以它可以触发一个UnicodeDecodeError。这会导致arglistNULL,因此您的函数将不带任何参数被调用。

所以我不完全确定这里的最佳解决方案。但我只是改变了两个代码,使用宽字符和unicode代替ascii,并重新构建了pyHook,而这似乎解决了这个问题。我认为它只适用于Python 3版本,但对于Python 2,我认为旧的pyHook仍然可以工作。

LPWSTR win_name = NULL; 

... 
// grab the window name if possible 
win_len = GetWindowTextLengthW(hwnd); 
if(win_len > 0) { 
    win_name = (LPWSTR) malloc(sizeof(wchar_t) * win_len + 1); 
    GetWindowTextW(hwnd, win_name, win_len + 1); 
} 

// pass the message on to the Python function 
arglist = Py_BuildValue("(iiiiiiiu)", wParam, kbd->vkCode, kbd->scanCode, ascii, 
         kbd->flags, kbd->time, hwnd, win_name); 

只用在他们的头衔非ASCII字符窗口时会出现问题:Skype是一个。

+0

所以这是一个PyHook的bug。有没有人向项目报告过这个? – 2016-02-13 08:56:09

+0

如何重建python库文件。看到我的完整问题[这里](http://stackoverflow.com/questions/35471744/how-to-rebuild-a-python-module-libary) – SUPERETDUPER 2016-02-18 02:36:15

+0

@MartijnPieters我已经提交了一个问题在他们的[Sourceforge页面]( https://sourceforge.net/p/pyhook/bugs/7/)。但最后一次提交是在2008年,所以我不确定会发生什么。 – erb 2017-04-12 12:47:32

相关问题