Как заблокировать виртуальный ящик, чтобы получить скриншот через SOAP API - PullRequest
4 голосов
/ 21 января 2020

Я пытаюсь использовать SOAP интерфейс Virtualbox 6.1 из Python, чтобы получить скриншот машины. Я могу запустить машину, но получаю ошибки блокировки всякий раз, когда пытаюсь получить макет экрана.

Это код:

import zeep

# helper to show the session lock status
def show_lock_state(session_id):
    session_state = service.ISession_getState(session_id)
    print('current session state:', session_state)

# connect
client = zeep.Client('http://127.0.0.1:18083?wsdl')
service = client.create_service("{http://www.virtualbox.org/}vboxBinding", 'http://127.0.0.1:18083?wsdl')
manager_id = service.IWebsessionManager_logon('fakeuser', 'fakepassword')
session_id = service.IWebsessionManager_getSessionObject(manager_id)

# get the machine id and start it
machine_id = service.IVirtualBox_findMachine(manager_id, 'Debian')
progress_id = service.IMachine_launchVMProcess(machine_id, session_id, 'gui')
service.IProgress_waitForCompletion(progress_id, -1)

print('Machine has been started!')
show_lock_state(session_id)

# unlock and then lock to be sure, doesn't have any effect apparently

service.ISession_unlockMachine(session_id)
service.IMachine_lockMachine(machine_id, session_id, 'Shared')


show_lock_state(session_id)

console_id = service.ISession_getConsole(session_id)
display_id = service.IConsole_getDisplay(console_id)
print(service.IDisplay_getGuestScreenLayout(display_id))

Машина запущена правильно, но последняя строка выдает ошибку VirtualBox error: rc=0x80004001, что из того, что я читаю, означает заблокированный сеанс.

Я попытался снова снять и получить блокировку, но даже если она прошла успешно, ошибка остается. Я просмотрел документацию, но не могу найти другие типы блокировок, которые я должен использовать, кроме блокировки записи, которую здесь нельзя использовать, так как машина работает. Я не смог найти ни одного примера на любом языке.

1 Ответ

1 голос
/ 27 января 2020

Я нашел Android приложение под названием VBoxManager с возможностью скриншота SOAP. Запустив его через прокси-сервер MITM, я восстановил выполняемые им вызовы и записал их как эквивалент Zeep. В случае, если кто-то заинтересован в будущем, последние строки приведенного выше сценария теперь:

console_id = service.ISession_getConsole(session_id)
display_id = service.IConsole_getDisplay(console_id)
resolution = service.IDisplay_getScreenResolution(display_id, 0)
print(f'display data: {resolution}')

image_data = service.IDisplay_takeScreenShotToArray(
    display_id,
    0,
    resolution['width'],
    resolution['height'],
    'PNG')

with open('screenshot.png', 'wb') as f:
    f.write(base64.b64decode(image_data))
...