OSDN Git Service

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