Ho creato uno script Python che sospenderebbe tutte le VM VirtualBox in esecuzione, quindi imposterò il sistema per eseguire lo script al logout come attività pianificata.
Non so quanto sia affidabile questo metodo. Come altri hanno notato, esistono dei limiti per quanto tempo il sistema attenderà il completamento di un'attività Winlogon 7002. Ma personalmente non ho avuto alcun problema nel fornire stati di salvataggio utilizzabili anche con più macchine virtuali in esecuzione su 4+ GB di RAM complessiva della VM.
Ecco i passaggi per configurarlo:
- Scarica e installa Python 2.7.x da python.org
- Crea il file di script Python da qualche parte sul tuo sistema usando Blocco note o qualsiasi altro editor di testo semplice (vedi sotto)
- Apri l'Utilità di pianificazione
- Scegli Azione -> Crea un'attività di base ... e usa la procedura guidata per creare un'attività con le seguenti impostazioni
- Un nome a tua scelta
- Avvia l'attività quando viene registrato un evento specifico
- Registro: sistema
- Fonte: Winlogon
- ID evento: 7002
- Avvia un programma
- Accanto a Programma / Script , inserisci il percorso completo del tuo
python.exe
, ad esempioc:\Python27\python.exe
- Accanto a Aggiungi argomenti , inserisci il percorso completo in cui hai inserito il file di script Python, ad esempio ho inserito il mio in una sottocartella della cartella dei miei documenti, quindi questo è
C:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
- Scegli Fine.
Ora le VM VirtualBox dovrebbero essere sospese al logout / riavvio / spegnimento.
Lo script Python per eseguire l'arresto è di seguito:
# 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()