boppreh / keyboard

Hook and simulate global keyboard events on Windows and Linux.
MIT License
3.79k stars 432 forks source link

Exception with Python 3.6.5 64 bit and pyinstaller #157

Open fireph opened 6 years ago

fireph commented 6 years ago

When using keyboard with python 3.6.5 64 bit and running inside of pyinstaller, this error is returned:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "threading.py", line 916, in _bootstrap_inner
  File "threading.py", line 864, in run
  File "site-packages\keyboard\__init__.py", line 296, in listen
  File "site-packages\keyboard\_winkeyboard.py", line 562, in listen
  File "site-packages\keyboard\_winkeyboard.py", line 555, in prepare_intercept
ctypes.ArgumentError: argument 3: <class 'OverflowError'>: int too long to convert

I found a couple of other issues on other projects describing the same issue: https://github.com/rene-aguirre/pywinusb/issues/30 https://github.com/jaraco/jaraco.windows/issues/7 https://stackoverflow.com/questions/44163105/python-3-5-1-amd64-ctypes-argumenterror-argument-1-class-overflowerror https://bitbucket.org/pyglet/pyglet/issues/147/ctypesargumenterror-argument-4-int-too

Not sure exactly how to solve this for keyboard, but I am using 0.13.1. This error does not appear for me when I force using 32 bit Python in pyinstaller. I also only see the error inside of pyinstaller, not when just running a project normally with Python 3.6.5 64 bit.

This is all being done on Windows 10.

fireph commented 6 years ago

It seems like the loading of kernel32 dll is not quite right. A few answers exist explaining a better way to do it: http://stackoverflow.com/a/33780664/205580 http://stackoverflow.com/a/17524073/205580

More about it here as well: https://stackoverflow.com/questions/23522055/error-when-unload-a-64bit-dll-using-ctypes-windll https://stackoverflow.com/questions/30146537/python-3-4-64-bit-kernel32-getmodulehandlew-returns-32-bit-address

boppreh commented 6 years ago

Thank you for the in-depth report, I'm working on it.

giladbarnea commented 6 years ago

Having the exact same issue. Any temporary workaround maybe, just to get the exe going? /edit: This happens exclusively with .add_hotkey. Other methods are fine (as far as I know)

taylorsmurphy commented 6 years ago

I figured out the easy workaround finally, @GbeTech this should work for you too.

in keyboard\_winkeyboard.py line 555 replace keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_callback, GetModuleHandleW(None), None) with keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_callback, ctypes.c_ulonglong(GetModuleHandleW(None)), None)

GetModuleHandleW needs to be wrapped in ctypes.c_ulonglong or you get the overflow error. If the problem happens in any other modules you come across, the fix should be similar.

I'm not sure if this is the right way to do it @boppreh, (perhaps it should be specified earlier, or conditional on 32 vs 64 bit, but it works for my system).

ChickenFeett commented 6 years ago

Are there plans to get this fixed on future release? Latest version still has this bug.

Searinox commented 6 years ago

Can confirm this issue on Python 2.7 and that the provided fix in the comments section works.

spyoungtech commented 6 years ago

Also encountered this issue. The suggestion by @taylorsmurphy fixes the issue for me.

Any chance of getting this change merged in? Any concerns or blockers to this?

boppreh commented 6 years ago

Hi @spyoungtech

taylorsmurphy's suggestion hardcodes the type to long long, which may not be correct.

The master branch should contain a fixed due to the related problems reported and fixed by #186. Can you check that the master branch works for you>

spyoungtech commented 6 years ago

Thanks for the speedy reply @boppreh -- I can confirm that using the master branch fixes the issue as well 👍