2014-10-02 21 views
7

Tôi đã viết mã này để quan sát sự kiện của một chuyển động phím tắt. Vấn đề dường như là khi kịch bản này được điều hành, các chương trình nhất định sẽ sụp đổ chương trình này, phun ra thông báo lỗi này:pythoncom treo trên KeyDown khi được sử dụng nối với các ứng dụng nhất định

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

Một số chương trình quan sát sụp đổ là: Skype, Sublime Văn bản 2

Sau một vài thử nghiệm tại gỡ lỗi nó, vấn đề dường như xảy ra trên dòng cuối cùng nhưng tôi dường như không thể thu hẹp nó xuống. Tôi cũng không hiểu ý nghĩa của KeyboardSwitch() như được trả về bởi các trình biên dịch ...

Tôi cũng đã tìm thấy rằng chương trình sẽ luân phiên trở lại thông báo lỗi này

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) 

là gì nguyên nhân và làm thế nào để tôi khắc phục điều này, đặc biệt vì nó chỉ xuất hiện cho chỉ 1 trong 2 phím được nhấn

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 Là người mới bắt đầu, tôi không quen thuộc với chức năng của pythoncom và các định nghĩa trực tuyến dường như khá mơ hồ. Một lời giải thích về chức năng của pythoncom và PumpMessages sẽ được đánh giá cao.

Cảm ơn

Trả lời

0

Nếu chỉ 1 trong mỗi 2 lần nhấn hoạt động, đó chắc chắn là vấn đề với giá trị trả về bị thiếu. Thử trả về Đúng hoặc Sai.

6

Tôi nghĩ rằng vấn đề là khi pyHook được gọi lại bởi Windows, điều đầu tiên nó làm là lấy tên cửa sổ cho cửa sổ bằng tiêu điểm.

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

Vì vậy, tôi nghĩ rằng vấn đề ở đây là, ngay cả khi GetWindowText không trở về ký tự rộng, nó có thể trở lại ký tự khác ASCII từ một bảng mã ANSI. Điều đó sẽ không thất bại, tuy nhiên, cho đến khi chúng ta làm điều này:

// 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); 

Ở đây, vì z trong chuỗi định dạng, dữ liệu trong biến win_name đang được chuyển đổi sang một unicode str với Py_BuildValue giả sử nó là ASCII . Nhưng nó không phải: và vì vậy nó có thể kích hoạt một UnicodeDecodeError. Điều này sau đó làm cho arglistNULL và do đó chức năng của bạn sẽ được gọi mà không có đối số.

Vì vậy, tôi không hoàn toàn chắc chắn về cách khắc phục tốt nhất ở đây. Nhưng tôi chỉ thay đổi cả hai bit của mã để sử dụng ký tự rộng và unicode thay vì ascii, và xây dựng lại pyHook, và điều đó dường như sửa chữa nó. Tôi nghĩ rằng nó sẽ chỉ làm việc trong các phiên bản Python 3, nhưng đối với Python 2, tôi nghĩ rằng pyHook cũ vẫn hoạt động anyway.

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); 

Vấn đề chỉ xảy ra với các cửa sổ với ký tự khác ASCII trong tiêu đề: Skype là một.

+0

Vì vậy, đây là lỗi với PyHook.Có ai báo cáo điều này cho dự án không? –

+0

Làm cách nào để xây dựng lại thư viện python. Xem câu hỏi đầy đủ của tôi [ở đây] (http://stackoverflow.com/questions/35471744/how-to-rebuild-a-python-module-libary) – SUPERETDUPER

+0

@MartijnPieters Tôi đã gửi một vấn đề trên [trang Sourceforge] của họ (https://sourceforge.net/p/pyhook/bugs/7/). Cam kết cuối cùng là trong năm 2008 tuy nhiên, vì vậy tôi không chắc chắn những gì mong đợi. – erb

Các vấn đề liên quan