2014-10-02 25 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

相關問題