Ivo@0: using System; Ivo@0: using System.Reflection; Ivo@0: using System.Runtime.InteropServices; Ivo@0: using System.Windows.Forms; Ivo@0: using System.Threading; Ivo@0: using VirtualBox; Ivo@0: Ivo@0: namespace ConsoleApplication1 { Ivo@0: class ProgramRun { Ivo@0: public static VBoxXPCOM VBoxXPCOM { get; private set; } Ivo@0: Object WaitingForProgress = null; Ivo@0: Ivo@0: public int Run(string[] args) { Ivo@0: IVirtualBox vb; Ivo@0: ISession sess; Ivo@0: if (Environment.OSVersion.Platform == PlatformID.Unix) { Ivo@0: VBoxXPCOM = new VBoxXPCOM(); Ivo@0: vb = VBoxXPCOM.VirtualBox; Ivo@0: sess = VBoxXPCOM.Session; Ivo@0: } else { Ivo@0: VBoxCOMInit(out vb, out sess); Ivo@0: } Ivo@0: Ivo@0: Console.WriteLine("VirtualBox version={0} revision={1}", vb.Version, vb.Revision); Ivo@0: Console.WriteLine("VirtualBox HomeFolder={0}", vb.HomeFolder); Ivo@0: Ivo@0: if (args.Length < 1) { Ivo@0: Console.Error.WriteLine("Usage: {0} machine-name-or-id", Assembly.GetExecutingAssembly().Location); Ivo@0: return 1; Ivo@0: } Ivo@0: IMachine m; Ivo@0: m = vb.FindMachine(args[0]); Ivo@0: Ivo@0: Console.WriteLine("Lock machine"); Ivo@0: m.LockMachine((Session)sess, LockType.LockType_Write); Ivo@0: try { Ivo@0: Framebuffer fb = new Framebuffer(); Ivo@0: sess.Console.Display.SetFramebuffer(0, fb); Ivo@0: Ivo@0: Console.WriteLine("Start GUI thread"); Ivo@0: Display disp = new Display(sess.Console, fb); Ivo@0: Ivo@0: Console.WriteLine("Power up..."); Ivo@0: //MonitorAndProcessEventsUntilCompleted(sess.Console.PowerUpPaused()); Ivo@0: Ivo@0: try { Ivo@0: disp.MonitorUntilCompleted(sess.Console.PowerUpPaused()); Ivo@0: Ivo@0: //Console.WriteLine("Resume"); Ivo@0: //sess.Console.Resume(); Ivo@0: Ivo@0: Application.Run(disp); Ivo@0: } finally { Ivo@0: if (VBoxXPCOM != null) VBoxXPCOM.EventQueue.ProcessPendingEvents(); Ivo@0: switch (sess.Console.State) { Ivo@0: case MachineState.MachineState_PoweredOff: Ivo@0: case MachineState.MachineState_Saved: Ivo@0: case MachineState.MachineState_Aborted: Ivo@0: break; Ivo@0: default: Ivo@0: Console.WriteLine("Power down"); Ivo@0: WaitingForProgress = null; Ivo@0: ThreadPool.QueueUserWorkItem(delegate(Object state) { Ivo@0: Console.WriteLine("Requesting SaveState"); Ivo@0: IProgress p = sess.Console.SaveState(); Ivo@0: Console.WriteLine("Waiting for SaveState completion"); Ivo@0: WaitingForProgress = p; Ivo@0: VBoxWaitComplete(p); Ivo@0: }); Ivo@0: ProcessEventsUntilCompleted(); Ivo@0: break; Ivo@0: } Ivo@0: } Ivo@0: } finally { Ivo@0: Console.WriteLine("Unlock machine"); Ivo@0: sess.UnlockMachine(); Ivo@0: if (VBoxXPCOM != null) VBoxXPCOM.EventQueue.ProcessPendingEvents(); Ivo@0: } Ivo@0: return 0; Ivo@0: } Ivo@0: Ivo@0: void VBoxCOMInit(out IVirtualBox vb, out ISession sess) { Ivo@0: //vb = (IVirtualBox)Activator.CreateInstance(Type.GetTypeFromProgID("VirtualBox.VirtualBox")); Ivo@0: //vb = (IVirtualBox)Activator.CreateInstance(typeof(VirtualBoxClass)); Ivo@0: //vb = (IVirtualBox)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("B1A7A4F2-47B9-4A1E-82B2-07CCD5323C3F"))); Ivo@0: vb = new VirtualBox.VirtualBoxClass(); Ivo@0: sess = new VirtualBox.SessionClass(); Ivo@0: } Ivo@0: Ivo@0: public void VBoxWaitComplete(IProgress p) { Ivo@0: uint prev = 0; Ivo@0: while (p.Completed == 0) { Ivo@0: if (p.Percent != prev) Console.Write("{0}% ", p.Percent); Ivo@0: prev = p.Percent; Ivo@0: p.WaitForCompletion(100); Ivo@0: } Ivo@0: if (p.ResultCode == 0) { Ivo@0: Console.WriteLine("done"); Ivo@0: } else { Ivo@0: Console.WriteLine("Error {0} {1}", p.ErrorInfo.ResultCode, p.ErrorInfo.Text); Ivo@0: throw new COMException(p.ErrorInfo.Text, p.ErrorInfo.ResultCode); Ivo@0: } Ivo@0: } Ivo@0: Ivo@0: public void MonitorAndProcessEventsUntilCompleted(IProgress p) { Ivo@0: MonitorProgressAsync(p); Ivo@0: ProcessEventsUntilCompleted(p); Ivo@0: } Ivo@0: public void MonitorProgressAsync(IProgress p) { Ivo@0: ThreadPool.QueueUserWorkItem(delegate(Object state) { Ivo@0: try { Ivo@0: VBoxWaitComplete(p); Ivo@0: } catch (Exception ex) { Ivo@0: Console.WriteLine(ex.ToString()); Ivo@0: } Ivo@0: }); Ivo@0: } Ivo@0: public void ProcessEventsUntilCompleted(IProgress p) { Ivo@0: do { Ivo@0: if (VBoxXPCOM != null) VBoxXPCOM.EventQueue.ProcessPendingEvents(); Ivo@0: Thread.Sleep(100); Ivo@0: } while (p.Canceled == 0 && p.Completed == 0); Ivo@0: Console.WriteLine("Event processing completed"); Ivo@0: } Ivo@0: public void ProcessEventsUntilCompleted() { Ivo@0: Console.WriteLine("Processing COM events..."); Ivo@0: do { Ivo@0: if (VBoxXPCOM != null) VBoxXPCOM.EventQueue.ProcessPendingEvents(); Ivo@0: Thread.Sleep(100); Ivo@0: } while (WaitingForProgress == null || ((WaitingForProgress as IProgress).Canceled == 0 && (WaitingForProgress as IProgress).Completed == 0)); Ivo@0: Console.WriteLine("COM Event processing completed"); Ivo@0: } Ivo@0: } Ivo@0: }