pythoncom crashes on KeyDown when used hooked to certain applications
Asked Answered
G

4

12

I wrote this code on to observe the event of a keydown motion. The problem appears to be that when this script is run, certain programs will crash this program, spitting out this error message:

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

Some programs observed to crash are: Skype, Sublime Text 2

After a few trials at debugging it, the problem appears to be occurring on the final line but I can't seem to narrow it down. I also don't understand the meaning of KeyboardSwitch() as returned by the compiler...

I have also found that the program would alternately return this error message

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)

What is the cause and how do I fix this, especially since it only appears for only 1 in 2 keys pressed

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

P.S. As a beginner, I'm not very familiar with the function of pythoncom and the online definitions appear to be rather vague. An explanation on the function of pythoncom and PumpMessages would be greatly appreciated.

Thanks

Grefe answered 2/10, 2014 at 8:4 Comment(0)
E
9

I think the problem is that when pyHook gets called back by Windows, the first thing it does is get the window name for the window with focus.

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

So I think the problem here is that, even if GetWindowText is not returning wide characters, it can return non-ascii characters from an ANSI codepage. That won't fail, however, until we do this:

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

Here, because of the z in the format string, the data in the win_name variable is being converted to a unicode str with Py_BuildValue assuming it is ASCII. But it's not: and so it can trigger a UnicodeDecodeError. This then causes the arglist to be NULL and therefore your function to be called with no arguments.

So I'm not completely sure on the best fix here. But I just changed both bits of code to use wide characters and unicode instead of ascii, and rebuilt pyHook, and that seemed to fix it. I think it will only work in Python 3 versions, but for Python 2, I think the old pyHook still works 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);
}

and

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

The problem occurs only with windows with non-ascii characters in their title: Skype is one.

Emelineemelita answered 26/10, 2015 at 23:10 Comment(5)
So this is a bug with PyHook. Did anyone report this to the project?Malacostracan
How do I rebuild the python libary. See my full question hereFirstling
@MartijnPieters I've filed an issue on their Sourceforge page. The last commit was in 2008 however, so I'm not sure what to expect.Berlioz
@Berlioz Also I think the problem only affects Python 3 and PyHook was only ever developed for Python 2 - so bugs are to be expected,Emelineemelita
@Emelineemelita You are right, but if a fix is this easy then it's worth integrating imo. FWIW, I found a fork which claims Python 3 support: pypi.python.org/pypi/PyHook3Berlioz
U
0

If only 1 out of each 2 presses works, it's definetely a problem with missing return value. Try returning either True or False.

Undernourished answered 5/12, 2014 at 11:28 Comment(0)
T
0

The TypeError: KeyboardSwitch() missing 8 required positional arguments: 'msg', 'vk_code', 'scan_code', 'ascii', 'flags', 'time', 'hwnd', and 'win_name' error message indicates that you are trying to call a function named KeyboardSwitch and have not provided values for all of the required arguments.

The error message lists the required arguments as 'msg', 'vk_code', 'scan_code', 'ascii', 'flags', 'time', 'hwnd', and 'win_name'. These are the names of the arguments that the KeyboardSwitch function expects to receive when it is called. You must provide a value for each of these arguments in the correct order when you call the function.

To fix this error, you will need to make sure that you are providing values for all of the required arguments when you call the KeyboardSwitch function. You may also want to check the documentation for the KeyboardSwitch function to make sure that you are using it correctly and understand what each of the required arguments represents.

Trigonometry answered 17/12, 2022 at 20:49 Comment(1)
So practicly what i said is: Download KeyboardSwitch library. That's it :)Trigonometry
S
-1

There's a pyhook for python3: https://github.com/Answeror/pyhook_py3k This bug has been fixed in this project.

Spae answered 3/11, 2017 at 3:5 Comment(2)
Can you add the link related to the bug as well.Harragan
I don't get the bug anymore but instead I get Process finished with exit code -1073740771 (0xC000041D)Dulciana

© 2022 - 2024 — McMap. All rights reserved.