0
|
1 ???using System; |
|
2 using System.Reflection; |
|
3 using System.Runtime.InteropServices; |
|
4 using System.Windows.Forms; |
|
5 using System.Threading; |
|
6 using VirtualBox; |
|
7 |
|
8 namespace ConsoleApplication1 { |
|
9 class ProgramRun { |
|
10 public static VBoxXPCOM VBoxXPCOM { get; private set; } |
|
11 Object WaitingForProgress = null; |
|
12 |
|
13 public int Run(string[] args) { |
|
14 IVirtualBox vb; |
|
15 ISession sess; |
|
16 if (Environment.OSVersion.Platform == PlatformID.Unix) { |
|
17 VBoxXPCOM = new VBoxXPCOM(); |
|
18 vb = VBoxXPCOM.VirtualBox; |
|
19 sess = VBoxXPCOM.Session; |
|
20 } else { |
|
21 VBoxCOMInit(out vb, out sess); |
|
22 } |
|
23 |
|
24 Console.WriteLine("VirtualBox version={0} revision={1}", vb.Version, vb.Revision); |
|
25 Console.WriteLine("VirtualBox HomeFolder={0}", vb.HomeFolder); |
|
26 |
|
27 if (args.Length < 1) { |
|
28 Console.Error.WriteLine("Usage: {0} machine-name-or-id", Assembly.GetExecutingAssembly().Location); |
|
29 return 1; |
|
30 } |
|
31 IMachine m; |
|
32 m = vb.FindMachine(args[0]); |
|
33 |
|
34 Console.WriteLine("Lock machine"); |
|
35 m.LockMachine((Session)sess, LockType.LockType_Write); |
|
36 try { |
|
37 Framebuffer fb = new Framebuffer(); |
|
38 sess.Console.Display.SetFramebuffer(0, fb); |
|
39 |
|
40 Console.WriteLine("Start GUI thread"); |
|
41 Display disp = new Display(sess.Console, fb); |
|
42 |
|
43 Console.WriteLine("Power up..."); |
|
44 //MonitorAndProcessEventsUntilCompleted(sess.Console.PowerUpPaused()); |
|
45 |
|
46 try { |
|
47 disp.MonitorUntilCompleted(sess.Console.PowerUpPaused()); |
|
48 |
|
49 //Console.WriteLine("Resume"); |
|
50 //sess.Console.Resume(); |
|
51 |
|
52 Application.Run(disp); |
|
53 } finally { |
|
54 if (VBoxXPCOM != null) VBoxXPCOM.EventQueue.ProcessPendingEvents(); |
|
55 switch (sess.Console.State) { |
|
56 case MachineState.MachineState_PoweredOff: |
|
57 case MachineState.MachineState_Saved: |
|
58 case MachineState.MachineState_Aborted: |
|
59 break; |
|
60 default: |
|
61 Console.WriteLine("Power down"); |
|
62 WaitingForProgress = null; |
|
63 ThreadPool.QueueUserWorkItem(delegate(Object state) { |
|
64 Console.WriteLine("Requesting SaveState"); |
|
65 IProgress p = sess.Console.SaveState(); |
|
66 Console.WriteLine("Waiting for SaveState completion"); |
|
67 WaitingForProgress = p; |
|
68 VBoxWaitComplete(p); |
|
69 }); |
|
70 ProcessEventsUntilCompleted(); |
|
71 break; |
|
72 } |
|
73 } |
|
74 } finally { |
|
75 Console.WriteLine("Unlock machine"); |
|
76 sess.UnlockMachine(); |
|
77 if (VBoxXPCOM != null) VBoxXPCOM.EventQueue.ProcessPendingEvents(); |
|
78 } |
|
79 return 0; |
|
80 } |
|
81 |
|
82 void VBoxCOMInit(out IVirtualBox vb, out ISession sess) { |
|
83 //vb = (IVirtualBox)Activator.CreateInstance(Type.GetTypeFromProgID("VirtualBox.VirtualBox")); |
|
84 //vb = (IVirtualBox)Activator.CreateInstance(typeof(VirtualBoxClass)); |
|
85 //vb = (IVirtualBox)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("B1A7A4F2-47B9-4A1E-82B2-07CCD5323C3F"))); |
|
86 vb = new VirtualBox.VirtualBoxClass(); |
|
87 sess = new VirtualBox.SessionClass(); |
|
88 } |
|
89 |
|
90 public void VBoxWaitComplete(IProgress p) { |
|
91 uint prev = 0; |
|
92 while (p.Completed == 0) { |
|
93 if (p.Percent != prev) Console.Write("{0}% ", p.Percent); |
|
94 prev = p.Percent; |
|
95 p.WaitForCompletion(100); |
|
96 } |
|
97 if (p.ResultCode == 0) { |
|
98 Console.WriteLine("done"); |
|
99 } else { |
|
100 Console.WriteLine("Error {0} {1}", p.ErrorInfo.ResultCode, p.ErrorInfo.Text); |
|
101 throw new COMException(p.ErrorInfo.Text, p.ErrorInfo.ResultCode); |
|
102 } |
|
103 } |
|
104 |
|
105 public void MonitorAndProcessEventsUntilCompleted(IProgress p) { |
|
106 MonitorProgressAsync(p); |
|
107 ProcessEventsUntilCompleted(p); |
|
108 } |
|
109 public void MonitorProgressAsync(IProgress p) { |
|
110 ThreadPool.QueueUserWorkItem(delegate(Object state) { |
|
111 try { |
|
112 VBoxWaitComplete(p); |
|
113 } catch (Exception ex) { |
|
114 Console.WriteLine(ex.ToString()); |
|
115 } |
|
116 }); |
|
117 } |
|
118 public void ProcessEventsUntilCompleted(IProgress p) { |
|
119 do { |
|
120 if (VBoxXPCOM != null) VBoxXPCOM.EventQueue.ProcessPendingEvents(); |
|
121 Thread.Sleep(100); |
|
122 } while (p.Canceled == 0 && p.Completed == 0); |
|
123 Console.WriteLine("Event processing completed"); |
|
124 } |
|
125 public void ProcessEventsUntilCompleted() { |
|
126 Console.WriteLine("Processing COM events..."); |
|
127 do { |
|
128 if (VBoxXPCOM != null) VBoxXPCOM.EventQueue.ProcessPendingEvents(); |
|
129 Thread.Sleep(100); |
|
130 } while (WaitingForProgress == null || ((WaitingForProgress as IProgress).Canceled == 0 && (WaitingForProgress as IProgress).Completed == 0)); |
|
131 Console.WriteLine("COM Event processing completed"); |
|
132 } |
|
133 } |
|
134 } |