Creé un script de Python que suspendería todas las máquinas virtuales de VirtualBox en ejecución y luego configuré el sistema para ejecutar el script al cerrar sesión como una tarea programada.
No sé qué tan confiable es este método exactamente. Como otros han señalado, hay límites en cuanto al tiempo que el sistema esperará a que se complete una tarea de Winlogon 7002. Pero, personalmente, no he tenido ningún problema al proporcionar estados de guardado utilizables incluso con múltiples máquinas virtuales en ejecución en más de 4 GB de RAM de VM en general.
Estos son los pasos para configurarlo:
- Descargue e instale Python 2.7.x desde python.org
- Cree el archivo de secuencia de comandos de Python en algún lugar de su sistema con el Bloc de notas o cualquier otro editor de texto sin formato (consulte a continuación)
- Abrir programador de tareas
- Elija Acción -> Crear una tarea básica ... y use el asistente para crear una tarea con la siguiente configuración
- Un nombre de tu elección
- Inicie la tarea cuando se registra un evento específico
- Registro: sistema
- Fuente: Winlogon
- Id. De evento: 7002
- Comience un programa
- Junto a Programa / Script , ingrese la ruta completa a su
python.exe
, por ejemploc:\Python27\python.exe
- Junto a Agregar argumentos , ingrese la ruta completa donde coloca el archivo de secuencia de comandos de Python, por ejemplo, coloco el mío en una subcarpeta de mi carpeta de documentos, así que esto es
C:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
- Elige Finalizar.
Ahora las máquinas virtuales de VirtualBox deberían suspenderse al cerrar sesión / reiniciar / apagar.
La secuencia de comandos de Python para hacer el apagado está a continuación:
# 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()