OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / EncodeQueue / Encode.cs
1 /*  Encode.cs $\r
2     This file is part of the HandBrake source code.\r
3     Homepage: <http://handbrake.fr/>.\r
4     It may be used under the terms of the GNU General Public License. */\r
5 \r
6 namespace Handbrake.EncodeQueue\r
7 {\r
8     using System;\r
9     using System.Diagnostics;\r
10     using System.IO;\r
11     using System.Windows.Forms;\r
12     using Functions;\r
13     using Properties;\r
14 \r
15     /// <summary>\r
16     /// Class which handles the CLI\r
17     /// </summary>\r
18     public class Encode\r
19     {\r
20         /// <summary>\r
21         /// Fires when a new CLI Job starts\r
22         /// </summary>\r
23         public event EventHandler EncodeStarted;\r
24 \r
25         /// <summary>\r
26         /// Fires when a CLI job finishes.\r
27         /// </summary>\r
28         public event EventHandler EncodeEnded;\r
29 \r
30         /// <summary>\r
31         /// Gets or sets The HB Process\r
32         /// </summary>\r
33         public Process HbProcess { get; set; }\r
34 \r
35         /// <summary>\r
36         /// Gets or sets The Process Handle\r
37         /// </summary>\r
38         public IntPtr ProcessHandle { get; set; }\r
39 \r
40         /// <summary>\r
41         /// Gets or sets a value indicating whether HandBrakeCLI.exe is running\r
42         /// </summary>\r
43         public bool IsEncoding { get; set; }\r
44 \r
45         /// <summary>\r
46         /// Gets or sets the Process ID\r
47         /// </summary>\r
48         private int ProcessID { get; set; }\r
49 \r
50         /// <summary>\r
51         /// Create a preview sample video\r
52         /// </summary>\r
53         /// <param name="query">\r
54         /// The CLI Query\r
55         /// </param>\r
56         public void CreatePreviewSample(string query)\r
57         {\r
58             this.Run(query);\r
59         }\r
60 \r
61         /// <summary>\r
62         /// Kill the CLI process\r
63         /// </summary>\r
64         public void Stop()\r
65         {\r
66             if (this.HbProcess != null)\r
67                 this.HbProcess.Kill();\r
68 \r
69             Process[] list = Process.GetProcessesByName("HandBrakeCLI");\r
70             foreach (Process process in list)\r
71                 process.Kill();\r
72 \r
73             this.IsEncoding = false;\r
74 \r
75             if (this.EncodeEnded != null)\r
76                 this.EncodeEnded(this, new EventArgs());\r
77         }\r
78 \r
79         /// <summary>\r
80         /// Attempt to Safely kill a DirectRun() CLI\r
81         /// NOTE: This will not work with a MinGW CLI\r
82         /// Note: http://www.cygwin.com/ml/cygwin/2006-03/msg00330.html\r
83         /// </summary>\r
84         public void SafelyClose()\r
85         {\r
86             if ((int) this.ProcessHandle == 0)\r
87                 return;\r
88 \r
89             // Allow the CLI to exit cleanly\r
90             Win32.SetForegroundWindow((int) this.ProcessHandle);\r
91             SendKeys.Send("^C");\r
92 \r
93             // HbProcess.StandardInput.AutoFlush = true;\r
94             // HbProcess.StandardInput.WriteLine("^C");\r
95         }\r
96 \r
97         /// <summary>\r
98         /// Execute a HandBrakeCLI process.\r
99         /// </summary>\r
100         /// <param name="query">\r
101         /// The CLI Query\r
102         /// </param>\r
103         protected void Run(string query)\r
104         {\r
105             try\r
106             {\r
107                 if (this.EncodeStarted != null)\r
108                     this.EncodeStarted(this, new EventArgs());\r
109 \r
110                 this.IsEncoding = true;\r
111 \r
112                 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");\r
113                 string logPath =\r
114                     Path.Combine(\r
115                         Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs", \r
116                         "last_encode_log.txt");\r
117                 string strCmdLine = String.Format(@" /C """"{0}"" {1} 2>""{2}"" """, handbrakeCLIPath, query, logPath);\r
118                 var cliStart = new ProcessStartInfo("CMD.exe", strCmdLine);\r
119 \r
120                 if (Settings.Default.enocdeStatusInGui)\r
121                 {\r
122                     cliStart.RedirectStandardOutput = true;\r
123                     cliStart.UseShellExecute = false;\r
124                     if (!Settings.Default.showCliForInGuiEncodeStatus)\r
125                         cliStart.CreateNoWindow = true;\r
126                 }\r
127                 if (Settings.Default.cli_minimized)\r
128                     cliStart.WindowStyle = ProcessWindowStyle.Minimized;\r
129 \r
130                 Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.\r
131                 this.HbProcess = Process.Start(cliStart);\r
132                 this.ProcessID = Main.GetCliProcess(before);\r
133 \r
134                 if (this.HbProcess != null)\r
135                     this.ProcessHandle = this.HbProcess.MainWindowHandle; // Set the process Handle\r
136 \r
137                 // Set the process Priority\r
138                 Process hbCliProcess = null;\r
139                 if (this.ProcessID != -1)\r
140                     hbCliProcess = Process.GetProcessById(this.ProcessID);\r
141 \r
142                 if (hbCliProcess != null)\r
143                     switch (Settings.Default.processPriority)\r
144                     {\r
145                         case "Realtime":\r
146                             hbCliProcess.PriorityClass = ProcessPriorityClass.RealTime;\r
147                             break;\r
148                         case "High":\r
149                             hbCliProcess.PriorityClass = ProcessPriorityClass.High;\r
150                             break;\r
151                         case "Above Normal":\r
152                             hbCliProcess.PriorityClass = ProcessPriorityClass.AboveNormal;\r
153                             break;\r
154                         case "Normal":\r
155                             hbCliProcess.PriorityClass = ProcessPriorityClass.Normal;\r
156                             break;\r
157                         case "Low":\r
158                             hbCliProcess.PriorityClass = ProcessPriorityClass.Idle;\r
159                             break;\r
160                         default:\r
161                             hbCliProcess.PriorityClass = ProcessPriorityClass.BelowNormal;\r
162                             break;\r
163                     }\r
164             }\r
165             catch (Exception exc)\r
166             {\r
167                 MessageBox.Show(\r
168                     "It would appear that HandBrakeCLI has not started correctly. You should take a look at the Activity log as it may indicate the reason why.\n\nDetailed Error Information: error occured in runCli()\n\n" +\r
169                     exc, \r
170                     "Error", \r
171                     MessageBoxButtons.OK, \r
172                     MessageBoxIcon.Error);\r
173             }\r
174         }\r
175 \r
176         /// <summary>\r
177         /// Function to run the CLI directly rather than via CMD\r
178         /// TODO: Code to handle the Log data has yet to be written.\r
179         /// TODO: Code to handle the % / ETA info has to be written.\r
180         /// </summary>\r
181         /// <param name="query">\r
182         /// The query.\r
183         /// </param>\r
184         protected void DirectRun(string query)\r
185         {\r
186             try\r
187             {\r
188                 if (this.EncodeStarted != null)\r
189                     this.EncodeStarted(this, new EventArgs());\r
190 \r
191                 this.IsEncoding = true;\r
192 \r
193                 // Setup the job\r
194                 string handbrakeCLIPath = Path.Combine(Environment.CurrentDirectory, "HandBrakeCLI.exe");\r
195                 var hbProc = new Process\r
196                                  {\r
197                                      StartInfo =\r
198                                          {\r
199                                              FileName = handbrakeCLIPath, \r
200                                              Arguments = query, \r
201                                              UseShellExecute = false, \r
202                                              RedirectStandardOutput = true, \r
203                                              RedirectStandardError = true, \r
204                                              RedirectStandardInput = true, \r
205                                              CreateNoWindow = false, \r
206                                              WindowStyle = ProcessWindowStyle.Minimized\r
207                                          }\r
208                                  };\r
209 \r
210                 // Setup the redirects\r
211                 hbProc.ErrorDataReceived += new DataReceivedEventHandler(HbProcErrorDataReceived);\r
212                 hbProc.OutputDataReceived += new DataReceivedEventHandler(HbProcOutputDataReceived);\r
213 \r
214                 // Start the process\r
215                 hbProc.Start();\r
216 \r
217                 // Set the Process Priority\r
218                 switch (Settings.Default.processPriority)\r
219                 {\r
220                     case "Realtime":\r
221                         hbProc.PriorityClass = ProcessPriorityClass.RealTime;\r
222                         break;\r
223                     case "High":\r
224                         hbProc.PriorityClass = ProcessPriorityClass.High;\r
225                         break;\r
226                     case "Above Normal":\r
227                         hbProc.PriorityClass = ProcessPriorityClass.AboveNormal;\r
228                         break;\r
229                     case "Normal":\r
230                         hbProc.PriorityClass = ProcessPriorityClass.Normal;\r
231                         break;\r
232                     case "Low":\r
233                         hbProc.PriorityClass = ProcessPriorityClass.Idle;\r
234                         break;\r
235                     default:\r
236                         hbProc.PriorityClass = ProcessPriorityClass.BelowNormal;\r
237                         break;\r
238                 }\r
239 \r
240                 // Set the class items\r
241                 this.HbProcess = hbProc;\r
242                 this.ProcessID = hbProc.Id;\r
243                 this.ProcessHandle = hbProc.Handle;\r
244             }\r
245             catch (Exception exc)\r
246             {\r
247                 Console.WriteLine(exc);\r
248             }\r
249         }\r
250 \r
251         /// <summary>\r
252         /// Perform an action after an encode. e.g a shutdown, standby, restart etc.\r
253         /// </summary>\r
254         protected void Finish()\r
255         {\r
256             if (this.EncodeEnded != null)\r
257                 this.EncodeEnded(this, new EventArgs());\r
258 \r
259             this.IsEncoding = false;\r
260 \r
261             // Growl\r
262             if (Settings.Default.growlQueue)\r
263                 GrowlCommunicator.Notify("Queue Completed", "Put down that cocktail...\nyour Handbrake queue is done.");\r
264 \r
265             // Do something whent he encode ends.\r
266             switch (Settings.Default.CompletionOption)\r
267             {\r
268                 case "Shutdown":\r
269                     Process.Start("Shutdown", "-s -t 60");\r
270                     break;\r
271                 case "Log Off":\r
272                     Win32.ExitWindowsEx(0, 0);\r
273                     break;\r
274                 case "Suspend":\r
275                     Application.SetSuspendState(PowerState.Suspend, true, true);\r
276                     break;\r
277                 case "Hibernate":\r
278                     Application.SetSuspendState(PowerState.Hibernate, true, true);\r
279                     break;\r
280                 case "Lock System":\r
281                     Win32.LockWorkStation();\r
282                     break;\r
283                 case "Quit HandBrake":\r
284                     Application.Exit();\r
285                     break;\r
286                 default:\r
287                     break;\r
288             }\r
289         }\r
290 \r
291         /// <summary>\r
292         /// Add the CLI Query to the Log File.\r
293         /// </summary>\r
294         /// <param name="encJob">\r
295         /// The Encode Job Object\r
296         /// </param>\r
297         protected void AddCLIQueryToLog(Job encJob)\r
298         {\r
299             try\r
300             {\r
301                 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +\r
302                                 "\\HandBrake\\logs";\r
303                 string logPath = Path.Combine(logDir, "last_encode_log.txt");\r
304 \r
305                 var reader =\r
306                     new StreamReader(File.Open(logPath, FileMode.Open, FileAccess.Read, FileShare.Read));\r
307                 string log = reader.ReadToEnd();\r
308                 reader.Close();\r
309 \r
310                 var writer = new StreamWriter(File.Create(logPath));\r
311 \r
312                 writer.Write("### CLI Query: " + encJob.Query + "\n\n");\r
313                 writer.Write("### User Query: " + encJob.CustomQuery + "\n\n");\r
314                 writer.Write("#########################################\n\n");\r
315                 writer.WriteLine(log);\r
316                 writer.Flush();\r
317                 writer.Close();\r
318             }\r
319             catch (Exception)\r
320             {\r
321                 return;\r
322             }\r
323         }\r
324 \r
325         /// <summary>\r
326         /// Save a copy of the log to the users desired location or a default location\r
327         /// if this feature is enabled in options.\r
328         /// </summary>\r
329         /// <param name="destination">\r
330         /// The Destination File Path\r
331         /// </param>\r
332         protected void CopyLog(string destination)\r
333         {\r
334             try\r
335             {\r
336                 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +\r
337                                 "\\HandBrake\\logs";\r
338                 string tempLogFile = Path.Combine(logDir, "last_encode_log.txt");\r
339 \r
340                 string encodeDestinationPath = Path.GetDirectoryName(destination);\r
341                 string destinationFile = Path.GetFileName(destination);\r
342                 string encodeLogFile = destinationFile + " " +\r
343                                        DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + ".txt";\r
344 \r
345                 // Make sure the log directory exists.\r
346                 if (!Directory.Exists(logDir))\r
347                     Directory.CreateDirectory(logDir);\r
348 \r
349                 // Copy the Log to HandBrakes log folder in the users applciation data folder.\r
350                 File.Copy(tempLogFile, Path.Combine(logDir, encodeLogFile));\r
351 \r
352                 // Save a copy of the log file in the same location as the enocde.\r
353                 if (Settings.Default.saveLogWithVideo)\r
354                     File.Copy(tempLogFile, Path.Combine(encodeDestinationPath, encodeLogFile));\r
355 \r
356                 // Save a copy of the log file to a user specified location\r
357                 if (Directory.Exists(Settings.Default.saveLogPath))\r
358                     if (Settings.Default.saveLogPath != String.Empty && Settings.Default.saveLogToSpecifiedPath)\r
359                         File.Copy(tempLogFile, Path.Combine(Settings.Default.saveLogPath, encodeLogFile));\r
360             }\r
361             catch (Exception exc)\r
362             {\r
363                 MessageBox.Show(\r
364                     "Something went a bit wrong trying to copy your log file.\nError Information:\n\n" + exc, \r
365                     "Error", \r
366                     MessageBoxButtons.OK, \r
367                     MessageBoxIcon.Error);\r
368             }\r
369         }\r
370 \r
371         /// <summary>\r
372         /// Recieve the Standard Error information and process it\r
373         /// </summary>\r
374         /// <param name="sender">\r
375         /// The Sender Object\r
376         /// </param>\r
377         /// <param name="e">\r
378         /// DataReceived EventArgs\r
379         /// </param>\r
380         private static void HbProcErrorDataReceived(object sender, DataReceivedEventArgs e)\r
381         {\r
382             // TODO: Recieve the Log data and process it\r
383             throw new NotImplementedException();\r
384         }\r
385 \r
386         /// <summary>\r
387         /// Standard Input Data Recieved from the CLI\r
388         /// </summary>\r
389         /// <param name="sender">\r
390         /// The Sender Object\r
391         /// </param>\r
392         /// <param name="e">\r
393         /// DataReceived EventArgs\r
394         /// </param>\r
395         private static void HbProcOutputDataReceived(object sender, DataReceivedEventArgs e)\r
396         {\r
397             // TODO: Recieve the %, ETA, FPS etc and process it\r
398             throw new NotImplementedException();\r
399         }\r
400     }\r
401 }