view 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 source
???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");
		}
	}
}