sethmlarson / virtualbox-python

Complete implementation of VirtualBox's COM API with a Pythonic interface.
https://pypi.org/project/virtualbox
Apache License 2.0
354 stars 75 forks source link

register_key_callback not working #124

Closed d4l3k closed 1 year ago

d4l3k commented 5 years ago
ENVIRONMENT
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'
ajay340 commented 5 years ago

Does this package work for Virtualbox 6.X?

sethmlarson commented 5 years ago

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

ajay340 commented 5 years ago

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

What verison of VirtualBox is working with package?

sethmlarson commented 5 years ago

Latest 5.x, working on 6.0 now.

sethmlarson commented 5 years ago

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

KarloDipetrio commented 4 years ago

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

sethmlarson commented 4 years ago

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

KarloDipetrio commented 4 years ago

ok, no problem!

KarloDipetrio commented 4 years ago

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

sethmlarson commented 1 year ago

I no longer have time to maintain this library, so am closing this issue.