Virtualbox Windows ปิดแขกอย่างสง่างามเมื่อโฮสต์ถูกปิด


19

ฉันกำลังพยายามหาวิธีแก้ปัญหาเพื่อปิดระบบ VM ของผู้เยี่ยมชมใด ๆ ที่ทำงานภายใต้ VirtualBox Windows เมื่อโฮสต์คอมพิวเตอร์ถูกปิดหรือรีสตาร์ท

ดูเหมือนว่าตัวเลือกที่ปลอดภัยที่สุดจะเรียกใช้คำสั่ง "บันทึกสถานะ" เมื่อโฮสต์เริ่มปิดระบบ แต่ไม่ชัดเจนว่าโฮสต์จะรอนานพอที่ VMs จะเสร็จสิ้นการบันทึกสถานะและปิดเครื่อง

ใครบ้างมีทางออกที่แข็งแกร่งสำหรับปัญหานี้ (ดูเหมือนพื้นฐาน)?


ติดตั้งสิ่งที่เพิ่มเติมจากแขก? ไม่ได้ให้ฟังก์ชั่นที่จำเป็น?
Canadian Luke ติดตั้ง MONICA ครั้งต่อไปใน

@CanadianLuke มันไม่ได้ :)
แมตต์เจนกินส์

คำตอบ:


6

ฉันมีปัญหาที่คล้ายกันและแก้ไขได้โดยใช้ VirtualBox เป็นบริการ:

http://vboxvmservice.sourceforge.net/

ด้วย VBoxVMService คุณสามารถเลือกว่าคุณต้องการให้เครื่องปิดเครื่องอย่างไร (บันทึกสถานะปิดเครื่อง) และเริ่มทำงาน เนื่องจากมันทำงานเป็นบริการ Windows จะรอให้ระบบปิดโดยอัตโนมัติในระหว่างกระบวนการปิดระบบ


ขั้นตอนการตั้งค่าไม่ได้เป็นไปโดยอัตโนมัติใน Windows 10 ฉันต้องอ้างถึงปัญหาในการถ่ายภาพเพื่อดูว่ามีอะไรผิดปกติ อย่างไรก็ตามหลังจากกำหนดค่าอย่างถูกต้องซอฟต์แวร์นี้จะทำสิ่งที่ฉันต้องการ ขอบคุณสำหรับการทำงานที่ดี
iuradz

3

น่าเสียดายที่ VM ไม่สามารถใช้งานได้ผ่าน VirtualBox GUI แม้ว่า GUI อาจตรวจจับเหตุการณ์การปิดโฮสต์และตอบสนองบริการ VirtualBox จะถูกยกเลิก: https://forums.virtualbox.org/viewtopic.php?p=278668#p278668

หากคุณไม่ต้องการคอนโซลกราฟิก VBoxHeadlessTray หรือ VBoxVMService อาจเป็นวิธีที่จะไป ทั้งสองสนับสนุนการบันทึกและดำเนินต่อโดยอัตโนมัติในการปิดโฮสต์ Windows และเริ่มต้นใหม่

VirtualBox 5.0 แนะนำโหมดเริ่มต้น"UI ที่ถอดออกได้" โหมดนี้เริ่มต้น VM แบบไร้หัวด้วยกระบวนการ UI แยกต่างหาก ประสิทธิภาพกราฟิกยังคงมีอยู่แม้ว่าจะยังไม่รองรับการเร่งความเร็ว 3D แต่บางทีนี้สามารถใช้ร่วมกับ VBoxHeadlessTray ในอนาคต (VBoxHeadlessTray ไม่สนับสนุน 5.0 ยัง.) เชื่อมโยงไปยังพื้นที่เก็บข้อมูล VBoxHeadlessTray GitHubและเพื่อให้สอดคล้องคำขอดึง GitHub สำหรับการเพิ่ม VirtualBox 5 การสนับสนุน

แก้ไข: VBoxVmService ยังไม่รองรับโหมดถอดออกได้ใหม่ในรุ่น 5.0 เพียงหัวขาดเพื่อให้ห่างไกล ฉันได้เพิ่มคำขอคุณลักษณะสำหรับสิ่งนั้น


เนื่องจากฉันไม่ได้รับอนุญาตให้พอร์ตมากกว่าสองลิงก์ต่อโพสต์นี่คือลิงค์ไปยังVBoxHeadlessTrayและไปยังคำขอดึงข้อมูล GitHub ที่เกี่ยวข้องสำหรับการเพิ่มการสนับสนุน VirtualBox 5
Leo B

ฉันไม่พบปัญหาที่ระบุไว้ในเธรด ดูคำตอบของฉันในหัวข้อนี้ ฉันสามารถเรียกใช้การปิดโฮสต์ Windows และเดินออกไป การปิดระบบจะปิดกั้นจนกว่า VMs ทั้งหมดของฉันจะปิดและฉันได้เปลี่ยนการกระทำเริ่มต้นเพื่อทำการปิดระบบใหม่ทั้งหมดหรือสถานะการบันทึก
Kris Bahnsen

2

ฉันมีสคริปต์แบทช์ 3 ชุดที่ฉันใช้แทนปุ่มเปิด / ปิดไฟ

do_shutdown.bat (ปิดเครื่องคอมพิวเตอร์ที่มีระยะเวลารอ 10 วินาทีไม่ใช่เวลา 10 วินาทีของ vm ให้ทำการกู้ แต่เพื่ออนุญาตให้ฉันยกเลิกการปิดเครื่องภายใน 10 วินาทีการนับถอยหลังเริ่มต้นหลังจากที่ vm ถูกปิดตัวลง)

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

do_reboot.bat (รีบูตทันทีหลังจาก vm ถูกปิด)

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

do_cancel.bat (อนุญาตให้ฉันยกเลิก pc-shutdown ภายในระยะเวลารอ 10 วินาทีจากนั้นรีสตาร์ท vm อีกครั้งเนื่องจากปิดด้วย do_shutdown.bat)

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

แทนที่จะใช้savestateคุณสามารถใช้วิธีใดวิธีหนึ่งต่อไปนี้

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
ขอบคุณนี่น่าสนใจ น่าเสียดายที่มีสถานการณ์การปิด / รีบูตแบบไม่มีคู่มืออื่น ๆ ที่ฉันต้องจัดการเช่นกัน ตัวอย่างเช่นรีสตาร์ทกำหนดเวลาโดย Windows Update หรือเหตุการณ์พลังงานปิด / ปิดแบตเตอรี่ต่ำ
Matt Jenkins

1
โอวตกลง. นอกจากนี้ยังมีตัวแก้ไขนโยบายกลุ่มกับ"สคริปต์ (เริ่มต้น / ปิดเครื่อง)"ส่วนlifehacker.com/...ฉันใช้ที่หนึ่งสำหรับคำสั่งที่สั้นมากในการปิด (หนึ่งสายขด) ดังนั้นฉันไม่ทราบว่ามันจะทำงาน บนสคริปต์ที่ใช้เวลาสักครู่จึงจะเสร็จสมบูรณ์
Daniel F

2

ขอโทษฉันมางานปาร์ตี้สาย มีคำตอบที่แน่นอนในเรื่องนี้แม้ว่ามันจะต้องมี commandline-foo ดูโพสต์กระทู้นี้สำหรับข้อมูลเพิ่มเติม: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

คำสั่งที่คุณต้องการคือ:

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

นี่คือสิ่งที่ฉันใช้บน VMs หลายแห่งปิดหน้าต่างและเริ่มการปิดเครื่องอย่างปลอดภัยโดยอัตโนมัติ ปิดระบบ Windows และในความพยายามที่จะปิดทุกอย่างมันจะรอกระบวนการเหล่านี้ให้เสร็จสมบูรณ์


1

ฉันมีคำถามที่คล้ายกันและพบหน้านี้ ฉันไม่ต้องการเรียกใช้ VirtualBox เป็นบริการเพราะฉันมีจำนวนมากของ VM สำหรับการทดสอบและมักจะเลือกคนอื่นให้ทำงานใน VirtualBox UI เมื่อฉันปิดคอมพิวเตอร์มันน่ารำคาญที่จะบันทึกสถานะของแต่ละ VM ด้วยตนเอง การใช้สคริปต์เพื่อบันทึก VM ที่ใช้งานอยู่ทั้งหมดดูเหมือนจะเป็นทางออกที่ใช้ได้จริงในกรณีนี้ เพื่อให้คำตอบของ Daniel F กว้างขึ้นฉันเขียนสคริปต์เหล่านี้โดยอัตโนมัติเพื่อบันทึกสถานะของ VM ที่ทำงานอยู่ทั้งหมดโดยไม่ต้องตั้งชื่อให้ชัดเจน

saveRunningVMs.batสำหรับ 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สำหรับ 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

0

ฉันสร้างสคริปต์ไพ ธ อนซึ่งจะระงับ VirtualBox VM ที่รันอยู่ทั้งหมดจากนั้นตั้งค่าระบบให้เรียกใช้สคริปต์เมื่อล็อกเอาต์เป็นงานที่กำหนดเวลาไว้

ฉันไม่รู้ว่าวิธีนี้น่าเชื่อถือเพียงใด ดังที่คนอื่น ๆ ระบุไว้ว่ามีข้อ จำกัด ว่าระบบจะรอให้งาน Winlogon 7002 ทำงานได้นานแค่ไหน แต่โดยส่วนตัวฉันไม่ได้มีปัญหาใด ๆ กับการให้สถานะการใช้งานที่ใช้งานได้แม้จะมีการใช้งาน VM หลายครั้งบน VM RAM โดยรวม 4+ GB

นี่คือขั้นตอนในการตั้งค่า:

  1. ดาวน์โหลดและติดตั้ง Python 2.7.x จาก python.org
  2. สร้างไฟล์สคริปต์หลามที่ใดที่หนึ่งในระบบของคุณโดยใช้ Notepad หรือโปรแกรมแก้ไขข้อความธรรมดาอื่น ๆ (ดูด้านล่าง)
  3. เปิด Task Scheduler
  4. เลือกการกระทำ -> สร้างงานพื้นฐาน ... และใช้ตัวช่วยสร้างเพื่อสร้างงานด้วยการตั้งค่าต่อไปนี้
    • ชื่อที่คุณเลือก
    • เริ่มงานเมื่อมีการบันทึกเหตุการณ์เฉพาะ
    • เข้าสู่ระบบ: ระบบ
    • ที่มา: Winlogon
    • รหัสเหตุการณ์: 7002
    • เริ่มโปรแกรม
    • ถัดจากProgram / Scriptให้ป้อนพา ธ เต็มของคุณpython.exeเช่นc:\Python27\python.exe
    • ถัดจากเพิ่มอาร์กิวเมนต์ให้ป้อนพา ธ แบบเต็มที่คุณใส่ไฟล์สคริปต์ของไพ ธ อนตัวอย่างเช่นฉันวางระเบิดลงในโฟลเดอร์ย่อยของโฟลเดอร์เอกสารของฉันดังนั้นนี่คือC:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • เลือกเสร็จสิ้น

ตอนนี้ VirtualBox VMs ควรถูกระงับเมื่อล็อกเอาต์ / รีสตาร์ท / ปิดเครื่อง

สคริปต์ python ในการปิดระบบอยู่ด้านล่าง:

# 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
ข้อเสนอแนะของผู้อื่นในการใช้ชุดสคริปต์ที่คุณสามารถเรียกใช้ด้วยตนเองที่จะช่วยให้รอดและจากนั้นการปิดระบบจะดีมากถ้าเหมาะกับกรณีการใช้งานของคุณ แต่สิ่งที่ฉันต้องการสำหรับ Windows Update คือการรีบูตอัตโนมัติโดยอัตโนมัติหลังจาก VM ที่ฉันทำงานด้วยถูกปิดฮาร์ดไดรฟ์ข้ามคืนโดย Windows Update จะรีสตาร์ทในสองวันที่ผ่านมาติดต่อกัน ...
rakslice
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.