pythoncom crashes on KeyDown when used hooked to certain applications
Solution 1:
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.