virtualbox-python
                                
                                 virtualbox-python copied to clipboard
                                
                                    virtualbox-python copied to clipboard
                            
                            
                            
                        Exception when starting VBox process (Objects for SAFEARRAYS must be sequences)
ENVIRONMENT
- Operating System: Windows Server 2012 R2 Standard (Build 9600)
- Python version: Python 3.7.4
- VirtualBox version: 6.1.2
- VirtualBox SDK version: 6.1.2
- Location where VirtualBox SDK is installed: C:\Users\Administrator\Downloads\sdk
- virtualbox-python / pyvbox version: virtualbox-python (2.0.0)
- [x] Happens in latest masterbranch?
SUMMARY
I fail to start VBox session when running example code provided in readme.
Machine I am trying to start is same as host Windows Server 2012 R2, it starts normally from the VBox GUI.
I printed the arguments of method _call_method from library_base.py that seems to be a problem:
<bound method IMachine.LaunchVMProcess of <win32com.gen_py.VirtualBox Type Library.IMachine instance at 0x1043591361928>
> [<virtualbox.library_ext.session.ISession object at 0x000000F2FB0CE6C8>, 'gui', '']
STEPS TO REPRODUCE
vbox.py
import virtualbox
vbox = virtualbox.VirtualBox()
session = virtualbox.Session()
machine = vbox.find_machine("Windows")
progress = machine.launch_vm_process(session, "gui", "")
progress.wait_for_completion()
EXPECTED RESULTS
VBox process started
ACTUAL RESULTS
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\virtualbox\library_base.py", lin
e 201, in _call_method
    ret = method(*in_params)
  File "C:\Users\ADMINI~1\AppData\Local\Temp\2\gen_py\3.7\D7569351-1750-46F0-936E-BD127D5BC264x0x1x3.py", line 7181, in
LaunchVMProcess
    , aName, aEnvironmentChanges)
TypeError: Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File ".\vbox.py", line 5, in <module>
    progress = machine.launch_vm_process(session, "gui", "")
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\virtualbox\library_ext\machine.p
y", line 183, in launch_vm_process
    type_p, environment)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\virtualbox\library.py", line 128
01, in launch_vm_process
    in_p=[session, name, environment])
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\virtualbox\library_base.py", lin
e 192, in _call
    return self._call_method(method, in_p=in_p)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\virtualbox\library_base.py", lin
e 214, in _call_method
    errobj.msg = exc.args[2][2]
IndexError: tuple index out of range
Any news about this issue? I have just started using this pibrary and I'm facing the same issue:
ENVIRONMENT Operating System: Windows 10 Pro 1909 Build 18363.657 Python version: Python 3.7.4 VirtualBox version: 6.1.2 r135662 VirtualBox SDK version: 6.1.2 virtualbox-python / pyvbox version: virtualbox-python (2.0.0)
The VM is working from the VBox GUI as usual.
I'm using the same basic steps to reproduce.
I'm wondering about some updates as well. This issue started to appear since I was forced to upgrade VirtualBox to version 6.1.2.
I have been able to locate the cause of the error, which is the parameter "" in machine.launch_vm_process(session, "gui", ""). When it's changed to bytes "".encode() the process finishes without error.
@MickyMickyMike Could you dig a little deeper into this change and potentially contribute a fix? Thanks! :)
Hi, I'm not a developer, so would take a lot o time to get into the real issue here, yet, I'm trying to understand the issue and help.
One test I did was install an older version of Virtualbox (5.2.36) and tested the same code and it worked:
import virtualbox
vbox = virtualbox.VirtualBox()
session = virtualbox.Session()
machine = vbox.find_machine("linux")
progress = machine.launch_vm_process(session, "gui","")
progress.wait_for_completion()
Went back to my main machine and tried to debug the code running with the VBox 6.1.2. With no luck.
So, digging into the SDK, I found the file sdk/bindings/glue/python/sample/vboxshell.py and a function startVm(ctx, mach, vmtype) where has a variable named asEnv=[] (an older SDK didn't have this variable) followed by a line:
progress = mach.launchVMProcess(session, vmtype, asEnv)
And testing the vboxshell.py it works with VBox 6.1.2.
Then, found the following code in the library.py:
        #line 12680
        def launch_vm_process(self, session, name, environment):
            ....
            #line 12798-12799
            if not isinstance(environment, basestring):
                raise TypeError("environment can only be an instance of type basestring")
So I commented the lines 12798-12799 and tested again. It worked.
For now I will be using like this, but I will not submit a PR as I don't really know what is wrong and how to fix it as I believe the type enforcement must have a reason.
I don't have exactly time to dig deeper into the problem, sorry. Frankly, I don't think I have the skill neither. I can commit this "workaround fix" if you want.
The problem seems to be an API change in VirtualBox API version 6_1. The method signature of LaunchVMProcess changed from:
HRESULT LaunchVMProcess (
        [in] ISession * aSession,
        [in] BSTR aName,
        [in] BSTR aEnvironment,
        [out, retval] IProgress * * aProgress
 );
(API version 5)
to:
HRESULT LaunchVMProcess (
        [in] ISession * aSession,
        [in] BSTR aName,
        [in] SAFEARRAY(BSTR) aEnvironmentChanges,
        [out, retval] IProgress * * aProgress
);
(API version 6_1)
A temporary fix would be allowing passing list as the environment parameter of launch_vm_process and passing empty list to this method.
        #line 12680
        def launch_vm_process(self, session, name, environment):
            ....
            #line 12798-12799
            if if not (isinstance(environment, basestring) or isinstance(environment, list)):
                raise TypeError("environment can only be an instance of type basestring or list")
# works
import virtualbox
vbox = virtualbox.VirtualBox()
session = virtualbox.Session()
machine = vbox.find_machine("Windows")
progress = machine.launch_vm_process(session, "gui", [])
progress.wait_for_completion()
Nice investigative work! Could you open a PR to fix this issue in the README / docs?