Ich habe ein Python-Skript erstellt, mit dem alle ausgeführten VirtualBox-VMs angehalten werden. Anschließend habe ich das System so eingerichtet, dass das Skript beim Abmelden als geplante Aufgabe ausgeführt wird.
Ich weiß nicht, wie zuverlässig diese Methode genau ist. Wie andere angemerkt haben, gibt es Einschränkungen, wie lange das System auf den Abschluss einer Winlogon 7002-Task warten soll. Aber ich persönlich hatte kein Problem damit, nutzbare Speicherzustände zu liefern, selbst wenn mehrere VMs mit mehr als 4 GB RAM ausgeführt werden.
Hier sind die Schritte zum Einrichten:
- Laden Sie Python 2.7.x von python.org herunter und installieren Sie es
- Erstellen Sie die Python-Skriptdatei irgendwo auf Ihrem System mit Notepad oder einem anderen Nur-Text-Editor (siehe unten).
- Öffnen Sie den Taskplaner
- Wählen Sie Aktion -> Grundlegende Aufgabe erstellen ... und erstellen Sie mit dem Assistenten eine Aufgabe mit den folgenden Einstellungen
- Ein Name Ihrer Wahl
- Starten Sie die Aufgabe, wenn ein bestimmtes Ereignis protokolliert wird
- Protokoll: System
- Quelle: Winlogon
- Ereignisid: 7002
- Starten Sie ein Programm
- Neben Programm / Skript , geben Sie den vollständigen Pfad zu Ihrem
python.exe
, zum Beispielc:\Python27\python.exe
- Geben Sie neben Argumente hinzufügen den vollständigen Pfad ein, in dem Sie die Python-Skriptdatei abgelegt haben, z. B. habe ich meine in einem Unterordner meines Dokumentenordners abgelegt
C:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
- Wählen Sie Finish.
Jetzt sollten VirtualBox-VMs beim Abmelden / Neustarten / Herunterfahren angehalten werden.
Das Python-Skript zum Herunterfahren ist unten:
# 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()