释放virtualbox时Win32异常

时间:2018-07-02 12:30:12

标签: python multithreading virtualbox pywin32

我正在尝试在线程中运行Virtualbox。在while循环的第二次迭代中,th变量被重新分配,应用程序崩溃并生成Win32异常。这似乎是由vbox和会话的发布引起的。我的问题是如何正确手动释放它们?

Win32 exception occurred releasing IUnknown at 0x035e40b8
Win32 exception occurred releasing IUnknown at 0x04babcb0

我的应用程序的基础知识(来自pyvbox和virtualbox sdk的virtualbox)

import virtualbox
import threading
import time


class ThreadExecutor(threading.Thread):
    def __init__(self):
        self.vbox = None
        self.session = None
        self.vm = None
        super().__init__()

    def run(self):
        self.vbox = virtualbox.VirtualBox()
        self.session = virtualbox.Session()
        self.vm = self.vbox.find_machine("Ubuntu")
        self.vm.launch_vm_process(self.session, 'gui', '')

        time.sleep(30)
        if int(self.session.state) == 1:
            print('Boot failed!')
            return
        else:
            print('Powering down')
            self.session.console.power_down()
        print('Operation completed')
        return


if __name__ == '__main__':
    while True:
        print('Input')
        if input():
            th = ThreadExecutor()
            th.start()
            print('Thread started')

            time.sleep(5)
            while th.isAlive():
                print('App running')
                time.sleep(5)
            print('Execution finished')

2 个答案:

答案 0 :(得分:0)

要可靠地释放会话,您应该使用try / except / finally结构,如下所示:

try:
   #Your code
except:
   print("something unexpected happend")
finally:
   self.session.console.power_down()

答案 1 :(得分:0)

我修改了代码(未运行):

  • 修复(错误的东西)并进行一些重组
  • 其他印刷

以解决问题并进行调试(无意修复此问题-至少在当前阶段不这样做)。

code.py

#!/usr/bin/env python3

import sys
import virtualbox
import threading
import time


DEFAULT_DEBUG_MSG_INDENT = "    "


def debug(text, indent_count, indent=DEFAULT_DEBUG_MSG_INDENT, leading_eoln_count=0):
    print("{:s}{:s}[TID: {:06d}]: {:s}".format("\n" * leading_eoln_count, indent * indent_count, threading.get_ident(), text))


class ThreadExecutor(threading.Thread):
    def __init__(self):
        super().__init__()
        self.vbox = virtualbox.VirtualBox()
        self.session = virtualbox.Session()
        if not self.vbox or not self.session:
            raise RuntimeError("virtualbox initialization failed")
        self.vm = self.vbox.find_machine("Ubuntu")
        if not self.vm:
            raise ValueError("VM not found")

    def run(self):
        start_wait_time = 15
        debug("Starting VM...", 1)
        self.vm.launch_vm_process(self.session, "gui", "")
        debug("Sleeping {:d} secs...".format(start_wait_time), 1)
        time.sleep(start_wait_time)
        if int(self.session.state) == 1:
            debug("Boot failed!", 1)
            return
        else:
            debug("Powering down", 1)
            self.session.console.power_down()
        debug("Operation completed", 1)


def run(threaded=True):
    debug("RUNNING with{:s} threads".format("" if threaded else "out"), 0, leading_eoln_count=1)
    sleep_time = 5
    while input("{:s}Press ANY key followed by ENTER to continue, ENTER ONLY to queet: ".format(DEFAULT_DEBUG_MSG_INDENT)):
        th = ThreadExecutor()
        if threaded:
            debug("Starting thread...", 0)
            th.start()
            debug("Thread started", 1)
            time.sleep(sleep_time)
            while th.isAlive():
                debug("App running", 1)
                time.sleep(sleep_time)
        else:
            debug("Running...", 0)
            th.run()
        debug("Execution finished", 1)
    debug("Done", 0)


def main():
    run(threaded=False)
    run()


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()

有效!

输出

(py35x64_test) e:\Work\Dev\StackOverflow\q051136288>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32


[TID: 036256]: RUNNING without threads
    Press ANY key followed by ENTER to continue, ENTER ONLY to queet: a
[TID: 036256]: Running...
    [TID: 036256]: Starting VM...
    [TID: 036256]: Sleeping 15 secs...
    [TID: 036256]: Powering down
    [TID: 036256]: Operation completed
    [TID: 036256]: Execution finished
    Press ANY key followed by ENTER to continue, ENTER ONLY to queet: a
[TID: 036256]: Running...
    [TID: 036256]: Starting VM...
    [TID: 036256]: Sleeping 15 secs...
    [TID: 036256]: Powering down
    [TID: 036256]: Operation completed
    [TID: 036256]: Execution finished
    Press ANY key followed by ENTER to continue, ENTER ONLY to queet:
[TID: 036256]: Done

[TID: 036256]: RUNNING with threads
    Press ANY key followed by ENTER to continue, ENTER ONLY to queet: a
[TID: 036256]: Starting thread...
    [TID: 038520]: Starting VM...
    [TID: 036256]: Thread started
    [TID: 038520]: Sleeping 15 secs...
    [TID: 036256]: App running
    [TID: 036256]: App running
    [TID: 036256]: App running
    [TID: 038520]: Powering down
    [TID: 038520]: Operation completed
    [TID: 036256]: Execution finished
    Press ANY key followed by ENTER to continue, ENTER ONLY to queet: a
[TID: 036256]: Starting thread...
    [TID: 028884]: Starting VM...
    [TID: 036256]: Thread started
    [TID: 028884]: Sleeping 15 secs...
    [TID: 036256]: App running
    [TID: 036256]: App running
    [TID: 036256]: App running
    [TID: 028884]: Powering down
    [TID: 028884]: Operation completed
    [TID: 036256]: Execution finished
    Press ANY key followed by ENTER to continue, ENTER ONLY to queet:
[TID: 036256]: Done

原始代码被抛出(仅相关部分):

  

pywintypes.com_error: (-2147221008, 'CoInitialize has not been called.', None, None)

我怀疑在初始化程序中移动 viralbox 初始化内容可能会导致行为更改(尽管正如我所说,我只是移动了代码,因为我认为初始化程序是正确的地方) -正确:将代码移回 run 再次触发了异常。

在对 virtualbox vboxapi 代码进行了简短检查之后,我认为这与 CoInitializeEx 所使用的位置(线程)有关。的地方,但我不能将手指放在上面。

我还尝试在主块中手动调用该函数(pythoncom.CoInitializeEx(0)),但是仅import pythoncom会触发该异常出现在1 st 迭代中。 / p>