diff VBoxFrontend/Program.cs @ 0:e1ec7bf71313

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