From adbb3094f0247a8e67f78ca01c6f9739f5d3336a Mon Sep 17 00:00:00 2001 From: sr55 Date: Sat, 23 May 2009 14:58:01 +0000 Subject: WinGui: - Renamed the Queue folder and moved the Encoding stuff into it. - Moves encode process information into a class object. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2445 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- win/C#/EncodeQueue/Encode.cs | 205 ++++++++++++++++++++++ win/C#/EncodeQueue/EncodeProcess.cs | 39 +++++ win/C#/EncodeQueue/QueueHandler.cs | 332 ++++++++++++++++++++++++++++++++++++ win/C#/EncodeQueue/QueueItem.cs | 31 ++++ 4 files changed, 607 insertions(+) create mode 100644 win/C#/EncodeQueue/Encode.cs create mode 100644 win/C#/EncodeQueue/EncodeProcess.cs create mode 100644 win/C#/EncodeQueue/QueueHandler.cs create mode 100644 win/C#/EncodeQueue/QueueItem.cs (limited to 'win/C#') diff --git a/win/C#/EncodeQueue/Encode.cs b/win/C#/EncodeQueue/Encode.cs new file mode 100644 index 000000000..8da86561a --- /dev/null +++ b/win/C#/EncodeQueue/Encode.cs @@ -0,0 +1,205 @@ +/* Encode.cs $ + + This file is part of the HandBrake source code. + Homepage: . + It may be used under the terms of the GNU General Public License. */ + +using System; +using System.Diagnostics; +using System.Windows.Forms; +using System.IO; +using System.Runtime.InteropServices; +using Handbrake.Functions; + +namespace Handbrake.EncodeQueue +{ + public class Encode + { + // DLL Imports + [DllImport("user32.dll")] + private static extern void LockWorkStation(); + [DllImport("user32.dll")] + private static extern int ExitWindowsEx(int uFlags, int dwReason); + + /// + /// Execute a HandBrakeCLI process. + /// + /// The CLI Query + public EncodeProcess runCli(string query) + { + EncodeProcess currentEncode = new EncodeProcess(); + try + { + string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe"); + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + string logPath = Path.Combine(logDir, "last_encode_log.txt"); + string strCmdLine = String.Format(@" CMD /c """"{0}"" {1} 2>""{2}"" """, handbrakeCLIPath, query, logPath); + + ProcessStartInfo cliStart = new ProcessStartInfo("CMD.exe", strCmdLine); + if (Properties.Settings.Default.enocdeStatusInGui == "Checked") + { + cliStart.RedirectStandardOutput = true; + cliStart.UseShellExecute = false; + } + if (Properties.Settings.Default.cli_minimized == "Checked") + cliStart.WindowStyle = ProcessWindowStyle.Minimized; + + Process[] before = Process.GetProcesses(); // Get a list of running processes before starting. + currentEncode.hbProcProcess = Process.Start(cliStart); + currentEncode.processID = Main.getCliProcess(before); + currentEncode.isEncoding = true; + currentEncode.currentQuery = query; + currentEncode.processHandle = (int)currentEncode.hbProcProcess.MainWindowHandle; // Set the process Handle + + // Set the process Priority + Process hbCliProcess = null; + if (currentEncode.processID != -1) + hbCliProcess = Process.GetProcessById(currentEncode.processID); + + if (hbCliProcess != null) + switch (Properties.Settings.Default.processPriority) + { + case "Realtime": + hbCliProcess.PriorityClass = ProcessPriorityClass.RealTime; + break; + case "High": + hbCliProcess.PriorityClass = ProcessPriorityClass.High; + break; + case "Above Normal": + hbCliProcess.PriorityClass = ProcessPriorityClass.AboveNormal; + break; + case "Normal": + hbCliProcess.PriorityClass = ProcessPriorityClass.Normal; + break; + case "Low": + hbCliProcess.PriorityClass = ProcessPriorityClass.Idle; + break; + default: + hbCliProcess.PriorityClass = ProcessPriorityClass.BelowNormal; + break; + } + } + catch (Exception exc) + { + MessageBox.Show("An error occured in runCli()\n Error Information: \n\n" + exc); + } + + return currentEncode; + } + + /// + /// Kill the CLI process + /// + public void closeCLI(EncodeProcess ep) + { + Process[] prs = Process.GetProcesses(); + foreach (Process process in prs) + { + if (process.Id == ep.processID) + { + process.Refresh(); + if (!process.HasExited) + process.Kill(); + + process.WaitForExit(); + } + } + } + + /// + /// Perform an action after an encode. e.g a shutdown, standby, restart etc. + /// + public void afterEncodeAction(EncodeProcess ep) + { + ep.isEncoding = false; + ep.currentQuery = String.Empty; + // Do something whent he encode ends. + switch (Properties.Settings.Default.CompletionOption) + { + case "Shutdown": + Process.Start("Shutdown", "-s -t 60"); + break; + case "Log Off": + ExitWindowsEx(0, 0); + break; + case "Suspend": + Application.SetSuspendState(PowerState.Suspend, true, true); + break; + case "Hibernate": + Application.SetSuspendState(PowerState.Hibernate, true, true); + break; + case "Lock System": + LockWorkStation(); + break; + case "Quit HandBrake": + Application.Exit(); + break; + default: + break; + } + } + + /// + /// Append the CLI query to the start of the log file. + /// + /// + public void addCLIQueryToLog(string query) + { + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + string logPath = Path.Combine(logDir, "last_encode_log.txt"); + + StreamReader reader = new StreamReader(File.Open(logPath, FileMode.Open, FileAccess.Read)); + String log = reader.ReadToEnd(); + reader.Close(); + + StreamWriter writer = new StreamWriter(File.Create(logPath)); + + writer.Write("### CLI Query: " + query + "\n\n"); + writer.Write("#########################################\n\n"); + writer.WriteLine(log); + writer.Flush(); + writer.Close(); + } + + /// + /// Save a copy of the log to the users desired location or a default location + /// if this feature is enabled in options. + /// + /// + public void copyLog(string destination) + { + try + { + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + string tempLogFile = Path.Combine(logDir, "last_encode_log.txt"); + + string encodeDestinationPath = Path.GetDirectoryName(destination); + String[] destName = destination.Split('\\'); + string destinationFile = destName[destName.Length - 1]; + string encodeLogFile = DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + " " + destinationFile + ".txt"; + + // Make sure the log directory exists. + if (!Directory.Exists(logDir)) + Directory.CreateDirectory(logDir); + + // Copy the Log to HandBrakes log folder in the users applciation data folder. + File.Copy(tempLogFile, Path.Combine(logDir, encodeLogFile)); + + // Save a copy of the log file in the same location as the enocde. + if (Properties.Settings.Default.saveLogWithVideo == "Checked") + File.Copy(tempLogFile, Path.Combine(encodeDestinationPath, encodeLogFile)); + + // Save a copy of the log file to a user specified location + if (Directory.Exists(Properties.Settings.Default.saveLogPath)) + if (Properties.Settings.Default.saveLogPath != String.Empty && Properties.Settings.Default.saveLogToSpecifiedPath == "Checked") + File.Copy(tempLogFile, Path.Combine(Properties.Settings.Default.saveLogPath, encodeLogFile)); + } + catch (Exception exc) + { + MessageBox.Show("Something went a bit wrong trying to copy your log file.\nError Information:\n\n" + exc, "Error", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + } +} \ No newline at end of file diff --git a/win/C#/EncodeQueue/EncodeProcess.cs b/win/C#/EncodeQueue/EncodeProcess.cs new file mode 100644 index 000000000..c65caea0d --- /dev/null +++ b/win/C#/EncodeQueue/EncodeProcess.cs @@ -0,0 +1,39 @@ +/* QueueItem.cs $ + + This file is part of the HandBrake source code. + Homepage: . + It may be used under the terms of the GNU General Public License. */ + +using System; +using System.Diagnostics; + +namespace Handbrake.EncodeQueue +{ + public class EncodeProcess + { + /// + /// The CMD.exe process that runs HandBrakeCLI.exe + /// + public Process hbProcProcess { get; set; } + + /// + /// Returns whether HandBrake is currently encoding or not. + /// + public Boolean isEncoding { get; set; } + + /// + /// Returns the currently encoding query string + /// + public String currentQuery { get; set; } + + /// + /// Get or set the process ID of HandBrakeCLI.exe + /// + public int processID { get; set; } + + /// + /// Get or Set the Process Handle + /// + public int processHandle { get; set; } + } +} \ No newline at end of file diff --git a/win/C#/EncodeQueue/QueueHandler.cs b/win/C#/EncodeQueue/QueueHandler.cs new file mode 100644 index 000000000..f34de0190 --- /dev/null +++ b/win/C#/EncodeQueue/QueueHandler.cs @@ -0,0 +1,332 @@ +/* QueueHandler.cs $ + + This file is part of the HandBrake source code. + Homepage: . + It may be used under the terms of the GNU General Public License. */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Windows.Forms; +using System.Xml.Serialization; +using System.Threading; +using System.Diagnostics; + +namespace Handbrake.EncodeQueue +{ + public class QueueHandler + { + Encode encodeHandler = new Encode(); + private static XmlSerializer ser = new XmlSerializer(typeof(List)); + List queue = new List(); + int id; // Unique identifer number for each job + + #region Queue Handling + public List getQueue() + { + return queue; + } + + /// + /// Get's the next CLI query for encoding + /// + /// String + private string getNextItemForEncoding() + { + QueueItem job = queue[0]; + String query = job.Query; + lastQueueItem = job; + remove(0); // Remove the item which we are about to pass out. + return query; + } + + /// + /// Get the last query that was returned by getNextItemForEncoding() + /// + /// + public QueueItem lastQueueItem { get; set; } + + /// + /// Add's a new item to the queue + /// + /// String + /// + /// + public void add(string query, string source, string destination) + { + QueueItem newJob = new QueueItem { Id = id, Query = query, Source = source, Destination = destination }; + id++; + + queue.Add(newJob); + } + + /// + /// Check to see if a destination path is already on the queue + /// + /// Destination path + /// Boolean True/False. True = Path Exists + public Boolean checkDestinationPath(string destination) + { + foreach (QueueItem checkItem in queue) + { + if (checkItem.Destination.Contains(destination.Replace("\\\\", "\\"))) + return true; + } + return false; + } + + /// + /// Removes an item from the queue. + /// + /// Index + /// Bolean true if successful + public void remove(int index) + { + queue.RemoveAt(index); + } + + /// + /// Returns how many items are in the queue + /// + /// Int + public int count() + { + return queue.Count; + } + + /// + /// Move an item with an index x, up in the queue + /// + /// Int + public void moveUp(int index) + { + if (index > 0) + { + QueueItem item = queue[index]; + + queue.RemoveAt(index); + queue.Insert((index - 1), item); + } + } + + /// + /// Move an item with an index x, down in the queue + /// + /// Int + public void moveDown(int index) + { + if (index < queue.Count - 1) + { + QueueItem item = queue[index]; + + queue.RemoveAt(index); + queue.Insert((index + 1), item); + } + } + + /// + /// Writes the current queue to disk. hb_queue_recovery.xml + /// This function is called after getNextItemForEncoding() + /// + public void write2disk(string file) + { + string tempPath = file == "hb_queue_recovery.xml" ? Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml") : file; + + try + { + using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write)) + { + ser.Serialize(strm, queue); + strm.Close(); + strm.Dispose(); + } + } + catch (Exception) + { + // Any Errors will be out of diskspace/permissions problems. + // Don't report them as they'll annoy the user. + } + } + + /// + /// Writes the current queue to disk to the location specified in file + /// + /// + public void writeBatchScript(string file) + { + string queries = ""; + foreach (QueueItem queue_item in queue) + { + string q_item = queue_item.Query; + string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + q_item; + + if (queries == string.Empty) + queries = queries + fullQuery; + else + queries = queries + " && " + fullQuery; + } + string strCmdLine = queries; + + if (file != "") + { + try + { + // Create a StreamWriter and open the file, Write the batch file query to the file and + // Close the stream + StreamWriter line = new StreamWriter(file); + line.WriteLine(strCmdLine); + line.Close(); + + MessageBox.Show("Your batch script has been sucessfully saved.", "Status", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + catch (Exception) + { + MessageBox.Show("Unable to write to the file. Please make sure that the location has the correct permissions for file writing.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + + } + } + + /// + /// Recover the queue from hb_queue_recovery.xml + /// + public void recoverQueue(string file) + { + string tempPath; + if (file == "hb_queue_recovery.xml") + tempPath = Path.Combine(Path.GetTempPath(), "hb_queue_recovery.xml"); + else + tempPath = file; + + if (File.Exists(tempPath)) + { + using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read)) + { + if (strm.Length != 0) + { + List list = ser.Deserialize(strm) as List; + + if (list != null) + foreach (QueueItem item in list) + queue.Add(item); + + if (file != "hb_queue_recovery.xml") + write2disk("hb_queue_recovery.xml"); + } + } + } + } + #endregion + + #region Encoding + + public Boolean isEncodeStarted { get; private set; } + public Boolean isPaused { get; private set; } + public Boolean isEncoding { get; private set; } + public EncodeProcess encodeProcess { get; set; } + + public void startEncode() + { + Thread theQueue; + if (this.count() != 0) + { + if (isPaused) + isPaused = false; + else + { + isPaused = false; + try + { + theQueue = new Thread(startProc) { IsBackground = true }; + theQueue.Start(); + } + catch (Exception exc) + { + MessageBox.Show(exc.ToString()); + } + } + } + } + public void pauseEncodeQueue() + { + isPaused = true; + EncodePaused(null); + } + public void endEncode() + { + encodeHandler.closeCLI(encodeProcess); + } + + private void startProc(object state) + { + try + { + // Run through each item on the queue + while (this.count() != 0) + { + string query = getNextItemForEncoding(); + write2disk("hb_queue_recovery.xml"); // Update the queue recovery file + + encodeProcess = encodeHandler.runCli(query); + EncodeStarted(null); + encodeProcess.hbProcProcess.WaitForExit(); + + encodeHandler.addCLIQueryToLog(query); + encodeHandler.copyLog(lastQueueItem.Destination); + + encodeProcess.hbProcProcess.Close(); + encodeProcess.hbProcProcess.Dispose(); + EncodeFinished(null); + + while (isPaused) // Need to find a better way of doing this. + { + Thread.Sleep(10000); + } + } + EncodeQueueFinished(null); + + // After the encode is done, we may want to shutdown, suspend etc. + encodeHandler.afterEncodeAction(encodeProcess); + } + catch (Exception exc) + { + throw new Exception(exc.ToString()); + } + } + #endregion + + #region Events + public event EventHandler OnEncodeStart; + public event EventHandler OnPaused; + public event EventHandler OnEncodeEnded; + public event EventHandler OnQueueFinished; + + // Invoke the Changed event; called whenever encodestatus changes: + protected virtual void EncodeStarted(EventArgs e) + { + if (OnEncodeStart != null) + OnEncodeStart(this, e); + + isEncoding = true; + } + protected virtual void EncodePaused(EventArgs e) + { + if (OnPaused != null) + OnPaused(this, e); + } + protected virtual void EncodeFinished(EventArgs e) + { + if (OnEncodeEnded != null) + OnEncodeEnded(this, e); + + isEncoding = false; + } + protected virtual void EncodeQueueFinished(EventArgs e) + { + if (OnQueueFinished != null) + OnQueueFinished(this, e); + } + #endregion + + } +} \ No newline at end of file diff --git a/win/C#/EncodeQueue/QueueItem.cs b/win/C#/EncodeQueue/QueueItem.cs new file mode 100644 index 000000000..587bfb73f --- /dev/null +++ b/win/C#/EncodeQueue/QueueItem.cs @@ -0,0 +1,31 @@ +/* QueueItem.cs $ + + This file is part of the HandBrake source code. + Homepage: . + It may be used under the terms of the GNU General Public License. */ + +namespace Handbrake.EncodeQueue +{ + public class QueueItem + { + /// + /// Get or Set the job id. + /// + public int Id { get; set; } + + /// + /// Get or Set the query string. + /// + public string Query { get; set; } + + /// + /// Get or set the source file of encoding + /// + public string Source { get; set; } + + /// + /// Get or set the destination for the file to be encoded. + /// + public string Destination { get; set; } + } +} \ No newline at end of file -- cgit v1.2.3