virtualbox-python icon indicating copy to clipboard operation
virtualbox-python copied to clipboard

register_key_callback not working

Open d4l3k opened this issue 6 years ago • 9 comments

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 master branch?
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'

d4l3k avatar Mar 24 '19 20:03 d4l3k

Does this package work for Virtualbox 6.X?

ajay340 avatar Apr 02 '19 23:04 ajay340

Not currently, would have to rebuild library.py with the latest API definition.

sethmlarson avatar Apr 02 '19 23:04 sethmlarson

Not currently, would have to rebuild library.py with the latest API definition.

What verison of VirtualBox is working with package?

ajay340 avatar Apr 03 '19 00:04 ajay340

Latest 5.x, working on 6.0 now.

sethmlarson avatar Apr 03 '19 00:04 sethmlarson

I can't reproduce this on my machine, callback is working successfully.

sethmlarson avatar Apr 03 '19 02:04 sethmlarson

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 avatar Oct 27 '20 11:10 KarloDipetrio

@KarloDipetrio Could you submit a PR? I have less and less time to work on this project unfortunately.

sethmlarson avatar Oct 27 '20 12:10 sethmlarson

ok, no problem!

KarloDipetrio avatar Oct 27 '20 12:10 KarloDipetrio

@sethmlarson Done! And thank you so much for this library =)

KarloDipetrio avatar Oct 27 '20 13:10 KarloDipetrio