Win32 исключение при выпуске виртуальной коробки - PullRequest
0 голосов
/ 02 июля 2018

Я пытаюсь запустить Virtualbox в потоке. Во время второй итерации цикла while, когда переменная th переопределяется, приложение вылетает и выдает исключение Win32. Кажется, это связано с выпуском vbox и сессии. У меня вопрос, как мне правильно отпустить их вручную?

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

Основы моего приложения (virtualbox от pyvbox и virtualbox sdk)

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 голосов
/ 06 июля 2018

Я изменил код (без его запуска):

  • Исправление (что-то не так) и некоторая реорганизация
  • Дополнительная печать

для работы и устранения неполадки (с нет намерения ее исправить - по крайней мере, на данном этапе).

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)

Я подозревал, что перемещение инициализации virualbox в инициализаторе может быть причиной изменения поведения (хотя, как я уже говорил, я перемещал код только потому, что считал инициализатор подходящим местом для него) - это было правильно: перемещение кода обратно в run снова вызвало исключение.

После краткой проверки кода virtualbox и vboxapi , я думаю, что это как-то связано с местом (потоком), где происходит CoInitializeEx , но Я не могу положить на это палец.

Я также пытался вызвать функцию вручную (pythoncom.CoInitializeEx(0)) в главном блоке, но только import pythoncom вызывал исключение, появляющееся в итерации 1 st .

0 голосов
/ 02 июля 2018

Чтобы сделать сеанс надежным, вы должны использовать конструкцию try / Кроме / Наконец, как это:

try:
   #Your code
except:
   print("something unexpected happend")
finally:
   self.session.console.power_down()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...