Ana bilgisayar kapatma sırasında misafirlerin Virtualbox Windows zarif kapanması


19

Ana bilgisayar kapatıldığında veya yeniden başlatıldığında VirtualBox Windows altında çalışan herhangi bir konuk VM'leri incelikle kapatmak için bir çözüm bulmaya çalışıyorum.

En güvenli seçenek, ana bilgisayar kapanmaya başladığında "kaydetme durumu" komutunu tetiklemek gibi görünüyor, ancak ana makinenin VM'lerin kaydetme durumunu ve gücü kapatmasını bitirmesi için yeterince bekleyip bekleyemeyeceği açık değil.

Herkes bu (görünüşte temel) sorun için sağlam bir çözüm var mı?


Konuk eklentileri yüklensin mi? Bu, gerekli işlevselliği sağlamaz mı?
Kanada Luke REINSTATE MONICA

@CanadianLuke Olmaz. :)
Matt Jenkins

Yanıtlar:


6

Ben benzer bir sorun vardı ve bir hizmet olarak VirtualBox çalıştırarak çözüldü:

http://vboxvmservice.sourceforge.net/

VBoxVMService ile makinenin nasıl kapanmasını (Durumu kaydet, kapat) ve başlatmasını istediğinizi seçebilirsiniz. Hizmet olarak çalıştığından, Windows sistem kapatma işlemi sırasında otomatik olarak kapanmasını bekleyecektir.


Kurulum işlemi Windows 10'da çok otomatik değil. Neyin yanlış olduğunu görmek için sorun gidermeye başvurmam gerekiyor. Ancak, doğru yapılandırıldıktan sonra, bu yazılım tam olarak ihtiyacım olanı yapar. Harika çalışmalarınız için teşekkür ederim.
Iuradz

3

Ne yazık ki bu, VirtualBox GUI ile başlatılan VM'ler için mümkün görünmüyor. GUI ana bilgisayar kapatma olayını yakalayıp tepki verebilse de, VirtualBox hizmeti sonlandırılır: https://forums.virtualbox.org/viewtopic.php?p=278668#p278668

Grafiksel bir konsola ihtiyacınız yoksa, VBoxHeadlessTray veya VBoxVMService gitmenin yolu olabilir. Her ikisi de Windows ana bilgisayar kapatma ve yeniden başlatma işlemlerinde otomatik kaydetme ve devam etmeyi destekler.

VirtualBox 5.0 bir "çıkarılabilir UI" başlatma modu sunar. Bu mod, ayrı bir UI işlemi ile başsız bir VM başlatır. Grafik performansı düşüyor ve 3D hızlandırma henüz desteklenmiyor. Ama belki de bu gelecekte VBoxHeadlessTray ile birleştirilebilir (VBoxHeadlessTray henüz 5.0'ı desteklemez.) VBoxHeadlessTray GitHub deposuna ve VirtualBox 5 desteği eklemek için karşılık gelen GitHub çekme isteğine bağlantılar .

Düzenleme: VBoxVmService ayrıca sürüm 5.0 itibariyle yeni çıkarılabilir modu desteklemiyor . Şimdiye kadar sadece başsız . Bunun için bir özellik isteği ekledim .


Gönderi başına ikiden fazla bağlantıya izin verilmediğim için, VBoxHeadlessTray ve VirtualBox 5 desteği eklemek için karşılık gelen GitHub çekme isteğine bağlantılar .
Leo B

Konu ana hatlarıyla belirtilen sorunları yaşamıyorum. Bu konudaki cevabımı görün. Windows ana bilgisayar kapatma çalıştırabilir ve uzaklaşabilirim. Tüm VM'lerim kapatılana kadar kapatma engelleri ve temiz bir kapatma veya kaydetme durumu yapmak için varsayılan işlemi değiştirdim.
Kris Bahnsen

2

Başlangıç ​​menüsü güç düğmeleri yerine kullandığım 3 toplu komut dosyası var.

do_shutdown.bat (10 saniyelik bekleme süresi olan kapatma bilgisayarı, vm'ye 10 saniye zaman kazandırmak için değil, 10 saniye içinde kapatmayı iptal etmeme izin vermek için. Geri sayım, vm'ler kapatıldıktan sonra başlar)

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

do_reboot.bat (vm kapatıldıktan hemen sonra yeniden başlatılır)

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

do_cancel.bat (10 saniyelik bekleme süresi içinde pc kapatmayı iptal etmeme izin veriyor. Daha sonra do_shutdown.bat ile kapatıldıklarından vm'leri yeniden başlatıyor)

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

Bunun yerine savestateaşağıdakilerden birini de kullanabilirsiniz

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)

1
Teşekkürler, bu ilginç. Ne yazık ki, ele almam gereken diğer manuel olmayan kapatma / yeniden başlatma senaryoları da var. Örneğin, Windows Update tarafından zamanlanan yeniden başlatmalar veya düşük pil gücü kapatma / kapatma olayları.
Matt Jenkins

1
Ah tamam. Orada da Grup İlkesi Düzenleyici ile "Komut Dosyaları (Başlangıç / Kapatma)" bölümünde lifehacker.com/... ben nasıl davranır bilmiyorum bu yüzden, Kapatma sırasında meydana gelen çok kısa komut için Şunu (bir bukle arama) kullanıyorum tamamlanması biraz zaman alan komut dosyalarında.
Daniel F

2

Üzgünüm partiye geç kaldım. Buna kesin bir cevap var, ancak bazı komut satırı foo gerektiriyor. Daha fazla bilgi için bu konuya bakın: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

Aradığınız komut:

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

Birden çok VM'de kullandığım bu, pencereyi kapatın ve otomatik olarak güvenli bir şekilde kapanmaya başlar. Windows'u kapatma ve her şeyi kapatma girişiminde bu işlemlerin tamamlanmasını bekler.


1

Benzer bir sorum vardı ve bu sayfayı buldum. Sınamak için VM'lerin bir sürü var ve genellikle VirtualBox kullanıcı arabiriminde çalıştırmak için farklı olanları seçin çünkü VirtualBox hizmet olarak çalıştırmak istemiyorum. Bilgisayarımı kapattığımda, her VM'nin durumunu manuel olarak kaydetmek can sıkıcı. Çalışan tüm VM'leri kaydetmek için komut dosyaları kullanmak bu durumda pratik bir çözüm gibi görünmektedir. Daniel F'nin cevabını daha genel hale getirmek için, çalışan tüm VM'lerin durumunu açıkça adlandırmadan otomatik olarak kaydeden bu komut dosyalarını yazdım.

Windows için saveRunningVMs.bat :

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

Linux için saveRunningVMs.sh :

#!/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

0

Çalışan tüm VirtualBox VM'lerini askıya alacak bir python betiği oluşturdum ve ardından sistemi oturum açmada komut dosyasını zamanlanmış bir görev olarak çalıştıracak şekilde ayarladım.

Bu yöntemin tam olarak ne kadar güvenilir olduğunu bilmiyorum. Diğerlerinin de belirttiği gibi , sistemin bir Winlogon 7002 görevinin tamamlanmasını ne kadar bekleyeceği konusunda sınırlamalar vardır. Ancak kişisel olarak, 4+ GB'lık genel VM RAM'de birden fazla çalışan VM ile bile kullanılabilir kaydetme durumları sağlamada herhangi bir sorun yaşamadım.

Ayarlamak için adımlar şunlardır:

  1. Python.org'dan Python 2.7.x dosyasını indirip yükleyin
  2. Not Defteri veya başka bir düz metin düzenleyici kullanarak python komut dosyasını sisteminizde bir yerde oluşturun (aşağıya bakın)
  3. Görev Zamanlayıcı'yı aç
  4. Eylem -> Temel Görev Oluştur ... seçeneğini belirleyin ve aşağıdaki ayarlarla bir görev oluşturmak için sihirbazı kullanın
    • Seçtiğiniz bir isim
    • Belirli bir olay günlüğe kaydedildiğinde görevi başlatın
    • Günlük: Sistem
    • Kaynak: Winlogon
    • Olay Kimliği: 7002
    • Bir Program Başlat
    • Sonraki Program / Komut , Blogunuza tam yolunu girin python.exeörneğinc:\Python27\python.exe
    • Nin yanında argümanlar ekle Bu yüzden mesela, piton komut dosyası koymak tam yolunu girin, ben klasörü benim belgelerin bir alt mayın koymakC:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • Son'u seçin.

Artık VirtualBox VM'lerinin oturum kapatma / yeniden başlatma / kapatma sırasında askıya alınması gerekir.

Kapatmayı yapacak python betiği aşağıdadır:

# 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()

1
Başkalarının el ile çalıştırabileceği bir toplu komut dosyası kullanma önerisi kaydeder ve daha sonra kullanım durumunuza uyarsa kapanma harikadır. Ama bunun için gerçekten istediğim şey, Windows Update otomatik yeniden başlatmaları, birlikte çalıştığım bir VM, Windows Update tarafından bir gecede son iki gün boyunca yeniden başlatıldıktan sonra
zorla kapatıldıktan sonra
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.