Virtualbox Windows shutdown tamu yang anggun pada host shutdown

19

Saya mencoba mencari solusi untuk mematikan semua VM tamu yang berjalan di bawah VirtualBox Windows dengan anggun ketika komputer host dimatikan atau dihidupkan ulang.

Tampaknya opsi paling aman adalah memicu perintah "save state" ketika tuan rumah mulai dimatikan, tetapi tidak jelas apakah tuan rumah akan menunggu cukup lama bagi VM untuk menyelesaikan keadaan simpan dan matikan.

Adakah yang punya solusi yang kuat untuk masalah ini (tampaknya mendasar)?

Matt Jenkins
sumber
Instal penambahan tamu? Apakah itu tidak menyediakan fungsionalitas yang diperlukan?
Luke Kanada REINSTATE MONICA
@ CanadianLuke Tidak. :)
Matt Jenkins

Jawaban:

6

Saya memiliki masalah serupa dan menyelesaikannya dengan menjalankan VirtualBox sebagai layanan:

http://vboxvmservice.sourceforge.net/

Dengan VBoxVMService Anda dapat memilih bagaimana Anda ingin mesin dimatikan (Hemat status, matikan) dan mulai. Karena berjalan sebagai layanan, Windows akan secara otomatis menunggu hingga shutdown, selama proses shutdown sistem.

Bill Westrup
sumber
Proses pengaturan tidak begitu otomatis pada Windows 10. Saya harus merujuk ke pemotretan masalah untuk melihat apa yang salah. Namun, setelah dikonfigurasi dengan benar, perangkat lunak ini melakukan apa yang saya butuhkan. Terima kasih atas kerja kerasnya.
iuradz
3

Sayangnya itu tampaknya tidak mungkin untuk VM mulai melalui VirtualBox GUI. Meskipun GUI mungkin menangkap peristiwa penutupan host dan bereaksi, layanan VirtualBox akan dihentikan: https://forums.virtualbox.org/viewtopic.php?p=278668#p278668

Jika Anda tidak memerlukan konsol grafis, VBoxHeadlessTray atau VBoxVMService mungkin merupakan cara yang tepat. Keduanya mendukung penyimpanan otomatis dan melanjutkan shutdown host Windows dan restart.

VirtualBox 5.0 memperkenalkan mode mulai "detachable UI" . Mode ini memulai VM tanpa kepala dengan proses UI yang terpisah. Performa grafisnya mengalami penurunan dan akselerasi 3D belum didukung. Tapi mungkin ini dapat dikombinasikan dengan VBoxHeadlessTray di masa depan (VBoxHeadlessTray belum mendukung 5.0.) Tautan ke repositori VBoxHeadlessTray GitHub dan ke permintaan tarik GitHub terkait untuk menambahkan dukungan VirtualBox 5 .

Sunting: VBoxVmService juga tidak mendukung mode yang dapat dilepas pada versi 5.0. Hanya tanpa kepala sejauh ini. Saya menambahkan permintaan fitur untuk itu.

Leo B
sumber
Karena saya tidak diizinkan untuk port lebih dari dua tautan per posting, berikut adalah tautan ke VBoxHeadlessTray dan permintaan tarik GitHub terkait untuk menambahkan dukungan VirtualBox 5.
Leo B
Saya tidak mengalami masalah yang diuraikan dalam utas. Lihat jawaban saya tentang topik ini. Saya dapat menjalankan shutdown host Windows dan berjalan pergi. Shutdown blok sampai semua VM saya ditutup, dan saya telah mengubah tindakan default untuk melakukan shutdown bersih atau keadaan simpan.
Kris Bahnsen
2

Saya memiliki 3 skrip batch yang saya gunakan sebagai ganti tombol power startmenu.

do_shutdown.bat (shutdown pc dengan masa tunggu 10 detik, bukan untuk memberi vm waktu 10 detik untuk melakukan penyelamatan, tetapi untuk memungkinkan saya membatalkan penutupan dalam waktu 10 detik. Hitung mundur dimulai setelah vm ditutup)

"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /s /t 10

do_reboot.bat (reboot segera setelah vm ditutup)

"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /r /t 0

do_cancel.bat (memungkinkan saya untuk membatalkan pc-shutdown dalam waktu tunggu 10 detik. Kemudian me-restart vm lagi, karena mereka dimatikan dengan do_shutdown.bat)

shutdown /a
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Minimal" --type headless
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Server" --type headless

Alih-alih savestateAnda juga dapat menggunakan salah satu dari yang berikut ini

poweroff        - pulls the plug
                  (probably not a good idea...)

acpipowerbutton - presses the power off button for a clean shutdown
                  ("The system is going down for power off NOW!" to all consoles)

acpisleepbutton - tells the os to go to sleep
                  (probably just as bad as poweroff)
Daniel F
sumber
1
Terima kasih, ini menarik. Sayangnya, ada skenario non-manual shutdown / reboot lain yang perlu saya tangani juga. Misalnya, restart dijadwalkan oleh Pembaruan Windows, atau acara mati / matikan baterai rendah.
Matt Jenkins
1
Oh oke. Ada juga Group Policy Editor dengan "Scripts (Startup / Shutdown)" bagian lifehacker.com/... Saya menggunakan yang satu untuk perintah yang sangat singkat di shutdown (satu keriting panggilan), jadi saya tidak tahu bagaimana berperilaku pada skrip yang membutuhkan waktu cukup lama untuk diselesaikan.
Daniel F
2

Maaf saya terlambat ke pesta. Ada jawaban yang tepat untuk ini, meskipun membutuhkan beberapa commandline-foo. Lihat posting utas ini untuk informasi lebih lanjut: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

Perintah yang Anda cari adalah:

"C: \ Program Files \ Oracle \ VirtualBox \ VBoxManage.exe" setextradata "VM NAME" GUI / DefaultCloseAction Shutdown

Ini yang saya gunakan pada banyak VM, tutup jendela dan dimatikan secara otomatis. Shutdown Windows, dan dalam upayanya untuk menutup semuanya, ia akan menunggu proses ini selesai.

Kris Bahnsen
sumber
1

Saya punya pertanyaan serupa dan menemukan halaman ini. Saya tidak ingin menjalankan VirtualBox sebagai layanan, karena saya memiliki banyak VM untuk pengujian, dan biasanya memilih yang berbeda untuk dijalankan di VirtualBox UI. Ketika saya mematikan komputer saya, itu mengganggu untuk secara manual menyimpan keadaan masing-masing VM. Menggunakan skrip untuk menyimpan semua VM yang berjalan tampaknya menjadi solusi praktis dalam kasus ini. Untuk membuat jawaban Daniel F lebih umum, saya menulis skrip-skrip ini yang secara otomatis menyimpan status semua VM yang berjalan tanpa menyebutkannya secara eksplisit.

saveRunningVMs.bat untuk Windows:

set VBoxManageEXE="%ProgramFiles%\Oracle\VirtualBox\VBoxManage.exe"
set ListRunningVMS=%VboxManageEXE% list runningvms
for /f tokens^=2^,4^ delims^=^" %%p in ('%ListRunningVMS%') do %VBoxManageEXE% controlvm %%p savestate

echo all vms saved, you can shutdown now.

rem shutdown /s /t 10

saveRunningVMs.sh untuk Linux:

#!/bin/bash
vboxmanage list runningvms | while read line; do
  #echo "VBoxManage controlvm $uuid savestate;"
  echo $line
  if [[ $line =~ \{(.*)\} ]]
  then
    vboxmanage controlvm ${BASH_REMATCH[1]} savestate
  fi
done
Karl Wolfram
sumber
0

Saya membuat skrip python yang akan menangguhkan semua menjalankan VirtualBox VMs, dan kemudian mengatur sistem untuk menjalankan skrip pada logout sebagai tugas yang dijadwalkan.

Saya tidak tahu seberapa andal metode ini. Seperti orang lain telah mencatat ada batasan untuk berapa lama sistem akan menunggu tugas Winlogon 7002 selesai. Tapi saya pribadi tidak punya masalah dengan itu memberikan negara menyimpan yang dapat digunakan bahkan dengan beberapa VM yang berjalan di 4+ GB dari keseluruhan VM RAM.

Berikut langkah-langkah untuk mengaturnya:

  1. Unduh dan instal Python 2.7.x dari python.org
  2. Buat file skrip python di suatu tempat di sistem Anda menggunakan Notepad atau editor teks biasa lainnya (lihat di bawah)
  3. Buka Penjadwal Tugas
  4. Pilih Aksi -> Buat Tugas Dasar ... dan gunakan wizard untuk membuat tugas dengan pengaturan berikut
    • Nama pilihan Anda
    • Mulai tugas saat peristiwa tertentu dicatat
    • Log: Sistem
    • Sumber: Winlogon
    • ID Peristiwa: 7002
    • Mulai Program
    • Di sebelah Program / Script , masukkan path lengkap ke Anda python.exe, misalnyac:\Python27\python.exe
    • Di sebelah Tambahkan argumen , masukkan path lengkap tempat Anda meletakkan file skrip python, misalnya saya meletakkan file saya di subfolder dari folder dokumen saya, jadi ini adalahC:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • Pilih Selesai.

Sekarang VirtualBox VMs harus ditangguhkan pada saat logout / restart / shutdown.

Skrip python untuk melakukan shutdown di bawah ini:

# A script to suspend all running VirtualBox VMs

import os

import subprocess

import sys


class VM(object):
    def __init__(self, name, uuid):
        self.name = name
        self.uuid = uuid

    def __repr__(self):
        return "VM(%r,%r)" % (self.name, self.uuid)


class VBoxRunner(object):
    def __init__(self):
        program_files = os.environ["ProgramW6432"]
        vbox_dir = os.path.join(program_files, "Oracle", "VirtualBox")
        self.vboxmanage_filename = os.path.join(vbox_dir, "VBoxManage.exe")

    def vbox_run(self, *args):
        subprocess.check_call([self.vboxmanage_filename] + list(args))

    def vbox_run_output(self, *args):
        return subprocess.check_output([self.vboxmanage_filename] + list(args))

    def list(self, running=True):
        if running:
            list_cmd = "runningvms"
        else:
            list_cmd = "vms"

        return [self.parse_vm_list_entry(x) for x in self.vbox_run_output("list", list_cmd).strip().split("\n")]

    def suspend_all(self):
        success = True
        stopped_some_vms = False
        vms = self.list(running=True)
        for vm in vms:
            if vm is None:
                continue
            # noinspection PyBroadException
            try:
                self.suspend_vm(vm)
            except:
                success = False
            else:
                stopped_some_vms = True
        if not stopped_some_vms:
            self.message("No running vms")
        return success

    @staticmethod
    def parse_vm_list_entry(x):
        """:type x: str"""
        if not x.startswith('"'):
            return None
        end_pos = x.find('"', 1)
        if end_pos == -1:
            return None
        name = x[1:end_pos]
        assert x[end_pos + 1: end_pos + 3] == " {"
        assert x.endswith("}")
        uuid = x[end_pos + 2:]

        return VM(name, uuid)

    @staticmethod
    def message(msg):
        print >>sys.stderr, msg

    def suspend_vm(self, vm):
        assert isinstance(vm, VM)
        self.vbox_run("controlvm", vm.uuid, "savestate")


def main():
    vr = VBoxRunner()
    success = vr.suspend_all()
    if not success:
        sys.exit(1)


if __name__ == "__main__":
    main()
rakslice
sumber
1
Saran orang lain untuk menggunakan skrip batch Anda dapat menjalankan secara manual yang melakukan savestate dan kemudian melakukan shutdown sangat bagus jika cocok dengan use case Anda. Tapi yang benar-benar saya inginkan adalah Pembaruan otomatis reboot Windows, setelah VM saya bekerja dengan keras dimatikan oleh Pembaruan Windows restart selama dua hari berturut-turut ...
rakslice