register_key_callback not working
ENVIRONMENT
- Operating System: Arch Linux
- Python version: Python 3.7.2
- VirtualBox version: virtualbox 6.0.4-4
- VirtualBox SDK version: virtualbox-sdk 6.0.4-4
- Location where VirtualBox SDK is installed: /usr/lib/virtualbox/sdk/
- pyvbox version: /usr/lib/virtualbox/sdk/
- [ ] Happens in latest
masterbranch?
SUMMARY
register_key_callback doesn't work correctly and throws an exception when trying to run the callback. It also causes the VBox VM to close.
There's also an exception that happens while handling the exception (which looks like a python3 compatibility issue).
STEPS TO REPRODUCE
import virtualbox
vbox = virtualbox.VirtualBox()
session = virtualbox.Session()
vm = vbox.find_machine('windows10')
progress = vm.launch_vm_process(session, 'gui', '')
# wait some time
def key_state(state, key):
print("key {} {}".format(state, key))
session.console.keyboard.register_key_callback(key_state)
EXPECTED RESULTS
It should log key events as they happen.
ACTUAL RESULTS
throws an error
Unhanded exception in callback:
Traceback (most recent call last):
File "/usr/lib/python3.7/site-packages/virtualbox/events.py", line 56, in _event_monitor
callback(event_interface(event))
File "/usr/lib/python3.7/site-packages/virtualbox/library_base.py", line 124, in __init__
self._i = manager.cast_object(interface, self.__class__)._i
File "/usr/lib/python3.7/site-packages/virtualbox/__init__.py", line 195, in cast_object
i = self.manager.queryInterface(interface_object._i, name)
File "/usr/lib/python3.7/site-packages/vboxapi/__init__.py", line 1078, in queryInterface
return self.platform.queryInterface(oIUnknown, sClassName)
File "/usr/lib/python3.7/site-packages/vboxapi/__init__.py", line 808, in queryInterface
return oIUnknown.queryInterface(getattr(xpcom.components.interfaces, sClassName))
AttributeError: 'NoneType' object has no attribute 'queryInterface'
Failed to unregister listener <virtualbox.library.IEventListener object at 0x7f4e334296a0>
Exception in thread Thread-5:
Traceback (most recent call last):
File "/usr/lib/python3.7/site-packages/virtualbox/library_base.py", line 195, in _call_method
ret = method(*in_params)
File "<XPCOMObject method 'eventProcessed'>", line 3, in eventProcessed
xpcom.Exception: 0x80004004 (Operation aborted (NS_ERROR_ABORT))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.7/site-packages/virtualbox/events.py", line 60, in _event_monitor
event_source.event_processed(listener, event)
File "/usr/lib/python3.7/site-packages/virtualbox/library.py", line 28678, in event_processed
in_p=[listener, event])
File "/usr/lib/python3.7/site-packages/virtualbox/library_base.py", line 186, in _call
return self._call_method(method, in_p=in_p)
File "/usr/lib/python3.7/site-packages/virtualbox/library_base.py", line 212, in _call_method
errobj.msg = getattr(exc, 'msg', getattr(exc, 'message'))
AttributeError: 'Exception' object has no attribute 'message'
Does this package work for Virtualbox 6.X?
Not currently, would have to rebuild library.py with the latest API definition.
Not currently, would have to rebuild library.py with the latest API definition.
What verison of VirtualBox is working with package?
Latest 5.x, working on 6.0 now.
I can't reproduce this on my machine, callback is working successfully.
same error when trying:
virtualbox.events.register_callback(callback, vm.session.console.event_source, VBoxEventType.on_vrde_server_info_changed)
But i think problem here:
events.py
def _event_monitor(callback, event_source, listener, event_interface, quit):
global _callbacks
try:
while not quit.is_set():
try:
event = event_source.get_event(listener, 1000)
except library.VBoxError:
print("Unregistering %s due to VBoxError on get_event" %
listener, file=sys.stderr)
break
if event:
try:
callback(event_interface(event))
except Exception:
print("Unhanded exception in callback: \n%s" %
traceback.format_exc(), file=sys.stderr)
event_source.event_processed(listener, event)
because get_event method from vbox sdk return null/none if available https://www.virtualbox.org/sdkref/interface_i_event_source.html#acfc3baef025a16a35ce0859b42c03077
and here need to replace:
library.py
def get_event(self, listener, timeout):
"""
...
"""
not isinstance(listener, IEventListener):
TypeError("listener can only be an instance of type IEventListener")
if not isinstance(timeout, baseinteger):
TypeError("timeout can only be an instance of type baseinteger")
event = self._call("getEvent", in_p=[listener, timeout])
# event = IEvent(event)
# return event
return IEvent(event) if event else None
And now all works fine for me
@KarloDipetrio Could you submit a PR? I have less and less time to work on this project unfortunately.
ok, no problem!
@sethmlarson Done! And thank you so much for this library =)