namespace HandBrake.ApplicationServices.Services\r
{\r
using System;\r
+ using System.ComponentModel;\r
using System.Diagnostics;\r
using System.IO;\r
using System.Text;\r
using System.Threading;\r
using System.Windows.Forms;\r
\r
+ using HandBrake.ApplicationServices.EventArgs;\r
using HandBrake.ApplicationServices.Functions;\r
using HandBrake.ApplicationServices.Model;\r
using HandBrake.ApplicationServices.Parsing;\r
- using HandBrake.ApplicationServices.Properties;\r
using HandBrake.ApplicationServices.Services.Interfaces;\r
-\r
- using Timer = System.Threading.Timer;\r
+ using HandBrake.ApplicationServices.Utilities;\r
\r
/// <summary>\r
/// Class which handles the CLI\r
/// </summary>\r
public class Encode : IEncode\r
{\r
- /* Private Variables */\r
-\r
- /// <summary>\r
- /// An Encode Job\r
- /// </summary>\r
- private Job job;\r
+ #region Private Variables\r
\r
/// <summary>\r
/// The Log Buffer\r
private StringBuilder logBuffer;\r
\r
/// <summary>\r
- /// The line number thats been read to in the log file\r
+ /// The Log file writer\r
/// </summary>\r
- private int logFilePosition;\r
-\r
- /// <summary>\r
- /// A Timer for this window\r
- /// </summary>\r
- private Timer windowTimer;\r
+ private StreamWriter fileWriter;\r
\r
/// <summary>\r
/// Gets The Process Handle\r
/// <summary>\r
/// Gets the Process ID\r
/// </summary>\r
- private int processID;\r
+ private int processId;\r
\r
/// <summary>\r
/// Windows 7 API Pack wrapper\r
/// </summary>\r
private Win7 windowsSeven = new Win7();\r
\r
- /* Constructor */\r
+ /// <summary>\r
+ /// A Lock for the filewriter\r
+ /// </summary>\r
+ static readonly object fileWriterLock = new object();\r
+\r
+ #endregion\r
\r
/// <summary>\r
/// Initializes a new instance of the <see cref="Encode"/> class.\r
/// </summary>\r
public Encode()\r
{\r
- this.EncodeStarted += Encode_EncodeStarted;\r
+ this.EncodeStarted += this.EncodeEncodeStarted;\r
+ GrowlCommunicator.Register();\r
}\r
\r
- /* Delegates */\r
+ #region Delegates and Event Handlers\r
\r
/// <summary>\r
- /// Encode Progess Status\r
- /// </summary>\r
- /// <param name="sender">\r
- /// The sender.\r
- /// </param>\r
- /// <param name="e">\r
- /// The EncodeProgressEventArgs.\r
- /// </param>\r
- public delegate void EncodeProgessStatus(object sender, EncodeProgressEventArgs e);\r
-\r
- /* Event Handlers */\r
-\r
- /// <summary>\r
- /// Fires when a new CLI Job starts\r
+ /// Fires when a new CLI QueueTask starts\r
/// </summary>\r
public event EventHandler EncodeStarted;\r
\r
/// <summary>\r
- /// Fires when a CLI job finishes.\r
+ /// Fires when a CLI QueueTask finishes.\r
/// </summary>\r
- public event EventHandler EncodeEnded;\r
+ public event EncodeCompletedStatus EncodeCompleted;\r
\r
/// <summary>\r
/// Encode process has progressed\r
/// </summary>\r
public event EncodeProgessStatus EncodeStatusChanged;\r
+ #endregion\r
\r
- /* Properties */\r
+ #region Properties\r
\r
/// <summary>\r
/// Gets or sets The HB Process\r
/// </summary>\r
public bool IsEncoding { get; private set; }\r
\r
- /* Public Methods */\r
-\r
/// <summary>\r
/// Gets ActivityLog.\r
/// </summary>\r
{\r
get\r
{\r
- if (logBuffer == null)\r
+ if (this.IsEncoding == false)\r
{\r
- ResetLogReader();\r
- ReadFile(null);\r
+ try\r
+ {\r
+ ReadFile(); // Read the last log file back in if it exists\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ return exc.ToString();\r
+ }\r
}\r
\r
- return logBuffer != null ? logBuffer.ToString() : string.Empty;\r
+ return string.IsNullOrEmpty(this.logBuffer.ToString()) ? "No log data available..." : this.logBuffer.ToString();\r
}\r
}\r
\r
- /// <summary>\r
- /// Create a preview sample video\r
- /// </summary>\r
- /// <param name="query">\r
- /// The CLI Query\r
- /// </param>\r
- public void CreatePreviewSample(string query)\r
- {\r
- this.Run(new Job { Query = query }, true);\r
- }\r
-\r
- /// <summary>\r
- /// Kill the CLI process\r
- /// </summary>\r
- public void Stop()\r
- {\r
- if (this.HbProcess != null)\r
- this.HbProcess.Kill();\r
-\r
- Process[] list = Process.GetProcessesByName("HandBrakeCLI");\r
- foreach (Process process in list)\r
- process.Kill();\r
-\r
- if (this.EncodeEnded != null)\r
- this.EncodeEnded(this, new EventArgs());\r
- }\r
-\r
- /// <summary>\r
- /// Attempt to Safely kill a DirectRun() CLI\r
- /// NOTE: This will not work with a MinGW CLI\r
- /// Note: http://www.cygwin.com/ml/cygwin/2006-03/msg00330.html\r
- /// </summary>\r
- public void SafelyClose()\r
- {\r
- if ((int)this.processHandle == 0)\r
- return;\r
+ #endregion\r
\r
- // Allow the CLI to exit cleanly\r
- Win32.SetForegroundWindow((int)this.processHandle);\r
- SendKeys.Send("^C");\r
- SendKeys.Flush();\r
-\r
- // HbProcess.StandardInput.AutoFlush = true;\r
- // HbProcess.StandardInput.WriteLine("^C");\r
- }\r
+ #region Public Methods\r
\r
/// <summary>\r
/// Execute a HandBrakeCLI process.\r
/// </summary>\r
- /// <param name="encJob">\r
- /// The enc Job.\r
+ /// <param name="encodeQueueTask">\r
+ /// The encodeQueueTask.\r
/// </param>\r
- /// <param name="requireStandardOuput">\r
- /// Set to True to show no window and force standard output redirect\r
+ /// <param name="enableLogging">\r
+ /// Enable Logging. When Disabled we onlt parse Standard Ouput for progress info. Standard Error log data is ignored.\r
/// </param>\r
- protected void Run(Job encJob, bool requireStandardOuput)\r
+ public void Start(QueueTask encodeQueueTask, bool enableLogging)\r
{\r
- this.job = encJob;\r
try\r
{\r
- if (Properties.Settings.Default.preventSleep)\r
+ QueueTask queueTask = encodeQueueTask;\r
+\r
+ if (queueTask == null)\r
{\r
- Win32.PreventSleep();\r
+ throw new ArgumentNullException("QueueTask was null");\r
}\r
\r
- ResetLogReader();\r
- IsEncoding = true;\r
-\r
- string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");\r
- string logPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs", "last_encode_log.txt");\r
- string strCmdLine = String.Format(@" /C """"{0}"" {1} 2>""{2}"" """, handbrakeCLIPath, encJob.Query, logPath);\r
- var cliStart = new ProcessStartInfo("CMD.exe", strCmdLine);\r
-\r
- if (Settings.Default.enocdeStatusInGui || requireStandardOuput)\r
+ if (IsEncoding)\r
{\r
- cliStart.RedirectStandardOutput = true;\r
- cliStart.UseShellExecute = false;\r
- if (!Settings.Default.showCliForInGuiEncodeStatus || requireStandardOuput)\r
- cliStart.CreateNoWindow = true;\r
+ throw new Exception("HandBrake is already encodeing.");\r
}\r
- if (Settings.Default.cli_minimized)\r
- cliStart.WindowStyle = ProcessWindowStyle.Minimized;\r
\r
- Process[] before = Process.GetProcesses(); // Get a list of running processes before starting.\r
- HbProcess = Process.Start(cliStart);\r
- this.processID = Main.GetCliProcess(before);\r
-\r
- this.processHandle = HbProcess.MainWindowHandle; // Set the process Handle\r
-\r
- // Start the Log Monitor\r
- windowTimer = new Timer(new TimerCallback(ReadFile), null, 1000, 1000);\r
+ IsEncoding = true;\r
\r
- // Set the process Priority\r
- Process hbCliProcess = null;\r
- if (this.processID != -1)\r
+ if (enableLogging)\r
{\r
- hbCliProcess = Process.GetProcessById(this.processID);\r
- hbCliProcess.EnableRaisingEvents = true;\r
- hbCliProcess.Exited += new EventHandler(HbProcess_Exited);\r
- }\r
-\r
- if (hbCliProcess != null)\r
- switch (Settings.Default.processPriority)\r
+ try\r
{\r
- case "Realtime":\r
- hbCliProcess.PriorityClass = ProcessPriorityClass.RealTime;\r
- break;\r
- case "High":\r
- hbCliProcess.PriorityClass = ProcessPriorityClass.High;\r
- break;\r
- case "Above Normal":\r
- hbCliProcess.PriorityClass = ProcessPriorityClass.AboveNormal;\r
- break;\r
- case "Normal":\r
- hbCliProcess.PriorityClass = ProcessPriorityClass.Normal;\r
- break;\r
- case "Low":\r
- hbCliProcess.PriorityClass = ProcessPriorityClass.Idle;\r
- break;\r
- default:\r
- hbCliProcess.PriorityClass = ProcessPriorityClass.BelowNormal;\r
- break;\r
+ SetupLogging(queueTask);\r
}\r
+ catch (Exception)\r
+ {\r
+ IsEncoding = false;\r
+ throw;\r
+ }\r
+ }\r
\r
- // Fire the Encode Started Event\r
- if (this.EncodeStarted != null)\r
- this.EncodeStarted(this, new EventArgs());\r
- }\r
- catch (Exception exc)\r
- {\r
- Main.ShowExceptiowWindow("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()", exc.ToString());\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// The HandBrakeCLI process has exited.\r
- /// </summary>\r
- /// <param name="sender">\r
- /// The sender.\r
- /// </param>\r
- /// <param name="e">\r
- /// The EventArgs.\r
- /// </param>\r
- private void HbProcess_Exited(object sender, EventArgs e)\r
- {\r
- IsEncoding = false;\r
+ if (Init.PreventSleep)\r
+ {\r
+ Win32.PreventSleep();\r
+ }\r
\r
- windowTimer.Dispose();\r
- ReadFile(null);\r
+ string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");\r
+ ProcessStartInfo cliStart = new ProcessStartInfo(handbrakeCLIPath, queueTask.Query)\r
+ {\r
+ RedirectStandardOutput = true,\r
+ RedirectStandardError = enableLogging ? true : false,\r
+ UseShellExecute = false,\r
+ CreateNoWindow = !Init.ShowCliForInGuiEncodeStatus ? true : false\r
+ };\r
\r
- if (this.EncodeEnded != null)\r
- this.EncodeEnded(this, new EventArgs());\r
+ this.HbProcess = new Process { StartInfo = cliStart };\r
\r
- if (windowsSeven.IsWindowsSeven)\r
- {\r
- windowsSeven.SetTaskBarProgressToNoProgress();\r
- }\r
+ this.HbProcess.Start();\r
\r
- if (Properties.Settings.Default.preventSleep)\r
- {\r
- Win32.AllowSleep();\r
- }\r
- }\r
+ if (enableLogging)\r
+ {\r
+ this.HbProcess.ErrorDataReceived += HbProcErrorDataReceived;\r
+ this.HbProcess.BeginErrorReadLine();\r
+ }\r
\r
- /// <summary>\r
- /// Function to run the CLI directly rather than via CMD\r
- /// TODO: Code to handle the Log data has yet to be written.\r
- /// TODO: Code to handle the % / ETA info has to be written.\r
- /// </summary>\r
- /// <param name="query">\r
- /// The query.\r
- /// </param>\r
- protected void DirectRun(string query)\r
- {\r
- try\r
- {\r
- if (this.EncodeStarted != null)\r
- this.EncodeStarted(this, new EventArgs());\r
+ this.processId = HbProcess.Id;\r
+ this.processHandle = HbProcess.Handle;\r
\r
- IsEncoding = true;\r
+ // Set the process Priority\r
+ if (this.processId != -1)\r
+ {\r
+ this.HbProcess.EnableRaisingEvents = true;\r
+ this.HbProcess.Exited += this.HbProcessExited;\r
+ }\r
\r
- ResetLogReader();\r
-\r
- // Setup the job\r
- string handbrakeCLIPath = Path.Combine(Environment.CurrentDirectory, "HandBrakeCLI.exe");\r
- HbProcess = new Process\r
- {\r
- StartInfo =\r
- {\r
- FileName = handbrakeCLIPath,\r
- Arguments = query,\r
- UseShellExecute = false,\r
- RedirectStandardOutput = true,\r
- RedirectStandardError = true,\r
- RedirectStandardInput = true,\r
- CreateNoWindow = false,\r
- WindowStyle = ProcessWindowStyle.Minimized\r
- }\r
- };\r
-\r
- // Setup event handlers for rediected data\r
- HbProcess.ErrorDataReceived += new DataReceivedEventHandler(HbProcErrorDataReceived);\r
- HbProcess.OutputDataReceived += new DataReceivedEventHandler(HbProcOutputDataReceived);\r
-\r
- // Start the process\r
- HbProcess.Start();\r
-\r
- // Setup the asynchronous reading of stdin and stderr\r
- HbProcess.BeginErrorReadLine();\r
- HbProcess.BeginOutputReadLine();\r
-\r
- // Set the Process Priority);\r
- switch (Settings.Default.processPriority)\r
+ // Set the Process Priority\r
+ switch (Init.ProcessPriority)\r
{\r
case "Realtime":\r
- HbProcess.PriorityClass = ProcessPriorityClass.RealTime;\r
+ this.HbProcess.PriorityClass = ProcessPriorityClass.RealTime;\r
break;\r
case "High":\r
- HbProcess.PriorityClass = ProcessPriorityClass.High;\r
+ this.HbProcess.PriorityClass = ProcessPriorityClass.High;\r
break;\r
case "Above Normal":\r
- HbProcess.PriorityClass = ProcessPriorityClass.AboveNormal;\r
+ this.HbProcess.PriorityClass = ProcessPriorityClass.AboveNormal;\r
break;\r
case "Normal":\r
- HbProcess.PriorityClass = ProcessPriorityClass.Normal;\r
+ this.HbProcess.PriorityClass = ProcessPriorityClass.Normal;\r
break;\r
case "Low":\r
- HbProcess.PriorityClass = ProcessPriorityClass.Idle;\r
+ this.HbProcess.PriorityClass = ProcessPriorityClass.Idle;\r
break;\r
default:\r
- HbProcess.PriorityClass = ProcessPriorityClass.BelowNormal;\r
+ this.HbProcess.PriorityClass = ProcessPriorityClass.BelowNormal;\r
break;\r
}\r
\r
- // Set the class items\r
- this.processID = HbProcess.Id;\r
- this.processHandle = HbProcess.Handle;\r
+ // Fire the Encode Started Event\r
+ if (this.EncodeStarted != null)\r
+ this.EncodeStarted(this, new EventArgs());\r
}\r
catch (Exception exc)\r
{\r
- Console.WriteLine(exc);\r
+ if (this.EncodeCompleted != null)\r
+ this.EncodeCompleted(this, new EncodeCompletedEventArgs(false, exc, "An Error has occured in EncodeService.Run()"));\r
}\r
}\r
\r
/// <summary>\r
- /// Add the CLI Query to the Log File.\r
+ /// Stop the Encode\r
/// </summary>\r
- /// <param name="encJob">\r
- /// The Encode Job Object\r
+ public void Stop()\r
+ {\r
+ this.Stop(null);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Kill the CLI process\r
+ /// </summary>\r
+ /// <param name="exc">\r
+ /// The Exception that has occured.\r
+ /// This will get bubbled up through the EncodeCompletedEventArgs\r
/// </param>\r
- protected void AddCLIQueryToLog(Job encJob)\r
+ public void Stop(Exception exc)\r
{\r
try\r
{\r
- string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +\r
- "\\HandBrake\\logs";\r
- string logPath = Path.Combine(logDir, "last_encode_log.txt");\r
-\r
- var reader = new StreamReader(File.Open(logPath, FileMode.Open, FileAccess.Read, FileShare.Read));\r
- string log = reader.ReadToEnd();\r
- reader.Close();\r
+ if (this.HbProcess != null && !this.HbProcess.HasExited)\r
+ {\r
+ this.HbProcess.Kill();\r
+ }\r
+ }\r
+ catch (Exception)\r
+ {\r
+ // No need to report anything to the user. If it fails, it's probably already stopped.\r
+ }\r
\r
- var writer = new StreamWriter(File.Create(logPath));\r
\r
- writer.WriteLine("### CLI Query: " + encJob.Query);\r
- writer.WriteLine("### User Query: " + encJob.CustomQuery);\r
- writer.WriteLine("#########################################");\r
- writer.WriteLine(log);\r
- writer.Flush();\r
- writer.Close();\r
+ if (exc == null)\r
+ {\r
+ if (this.EncodeCompleted != null)\r
+ this.EncodeCompleted(this, new EncodeCompletedEventArgs(true, null, string.Empty));\r
}\r
- catch (Exception)\r
+ else\r
{\r
- return;\r
+ if (this.EncodeCompleted != null)\r
+ this.EncodeCompleted(this, new EncodeCompletedEventArgs(false, exc, "An Error has occured."));\r
}\r
}\r
\r
/// <summary>\r
+ /// Attempt to Safely kill a DirectRun() CLI\r
+ /// NOTE: This will not work with a MinGW CLI\r
+ /// Note: http://www.cygwin.com/ml/cygwin/2006-03/msg00330.html\r
+ /// </summary>\r
+ public void SafelyStop()\r
+ {\r
+ if ((int)this.processHandle == 0)\r
+ return;\r
+\r
+ // Allow the CLI to exit cleanly\r
+ Win32.SetForegroundWindow((int)this.processHandle);\r
+ SendKeys.Send("^C");\r
+ SendKeys.Flush();\r
+\r
+ /*/if (HbProcess != null)\r
+ //{\r
+ // HbProcess.StandardInput.AutoFlush = true;\r
+ // HbProcess.StandardInput.WriteLine("^c^z");\r
+ //}*/\r
+ }\r
+\r
+ /// <summary>\r
/// Save a copy of the log to the users desired location or a default location\r
/// if this feature is enabled in options.\r
/// </summary>\r
/// <param name="destination">\r
/// The Destination File Path\r
/// </param>\r
- protected void CopyLog(string destination)\r
+ public void ProcessLogs(string destination)\r
{\r
try\r
{\r
string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +\r
"\\HandBrake\\logs";\r
- string tempLogFile = Path.Combine(logDir, "last_encode_log.txt");\r
+ string tempLogFile = Path.Combine(logDir, string.Format("last_encode_log{0}.txt", Init.InstanceId));\r
\r
string encodeDestinationPath = Path.GetDirectoryName(destination);\r
string destinationFile = Path.GetFileName(destination);\r
File.Copy(tempLogFile, Path.Combine(logDir, encodeLogFile));\r
\r
// Save a copy of the log file in the same location as the enocde.\r
- if (Settings.Default.saveLogWithVideo)\r
+ if (Init.SaveLogWithVideo)\r
File.Copy(tempLogFile, Path.Combine(encodeDestinationPath, encodeLogFile));\r
\r
// Save a copy of the log file to a user specified location\r
- if (Directory.Exists(Settings.Default.saveLogPath))\r
- if (Settings.Default.saveLogPath != String.Empty && Settings.Default.saveLogToSpecifiedPath)\r
- File.Copy(tempLogFile, Path.Combine(Settings.Default.saveLogPath, encodeLogFile));\r
+ if (Directory.Exists(Init.SaveLogPath))\r
+ if (Init.SaveLogPath != String.Empty && Init.SaveLogToSpecifiedPath)\r
+ File.Copy(tempLogFile, Path.Combine(Init.SaveLogPath, encodeLogFile));\r
}\r
catch (Exception exc)\r
{\r
- Main.ShowExceptiowWindow("Unable to make a copy of the log file", exc.ToString());\r
+ // This exception doesn't warrent user interaction, but it should be logged (TODO)\r
}\r
}\r
\r
+ #endregion\r
+\r
+ #region Private Helper Methods\r
+\r
/// <summary>\r
- /// Read the log file\r
+ /// The HandBrakeCLI process has exited.\r
/// </summary>\r
- /// <param name="n">\r
- /// The object.\r
+ /// <param name="sender">\r
+ /// The sender.\r
/// </param>\r
- private void ReadFile(object n)\r
+ /// <param name="e">\r
+ /// The EventArgs.\r
+ /// </param>\r
+ private void HbProcessExited(object sender, EventArgs e)\r
+ {\r
+ IsEncoding = false;\r
+ if (windowsSeven.IsWindowsSeven)\r
+ {\r
+ windowsSeven.SetTaskBarProgressToNoProgress();\r
+ }\r
+\r
+ if (Init.PreventSleep)\r
+ {\r
+ Win32.AllowSleep();\r
+ }\r
+\r
+ try\r
+ {\r
+ lock (fileWriterLock)\r
+ {\r
+ // This is just a quick hack to ensure that we are done processing the logging data.\r
+ // Logging data comes in after the exit event has processed sometimes. We should really impliment ISyncronizingInvoke\r
+ // and set the SyncObject on the process. I think this may resolve this properly.\r
+ // For now, just wait 2.5 seconds to let any trailing log messages come in and be processed.\r
+ Thread.Sleep(2500);\r
+\r
+ this.HbProcess.CancelErrorRead();\r
+\r
+ if (fileWriter != null)\r
+ {\r
+ fileWriter.Close();\r
+ fileWriter.Dispose();\r
+ }\r
+\r
+ fileWriter = null;\r
+ }\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ // This exception doesn't warrent user interaction, but it should be logged (TODO)\r
+ }\r
+\r
+ if (this.EncodeCompleted != null)\r
+ this.EncodeCompleted(this, new EncodeCompletedEventArgs(true, null, string.Empty));\r
+ }\r
+\r
+ /// <summary>\r
+ /// Read the log file\r
+ /// </summary>\r
+ private void ReadFile()\r
{\r
+ logBuffer = new StringBuilder();\r
lock (logBuffer)\r
{\r
// last_encode_log.txt is the primary log file. Since .NET can't read this file whilst the CLI is outputing to it (Not even in read only mode),\r
// we'll need to make a copy of it.\r
- string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +\r
- "\\HandBrake\\logs";\r
- string logFile = Path.Combine(logDir, "last_encode_log.txt");\r
- string logFile2 = Path.Combine(logDir, "tmp_appReadable_log.txt");\r
+ string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
+ string logFile = Path.Combine(logDir, string.Format("last_encode_log{0}.txt", Init.InstanceId));\r
+ string logFile2 = Path.Combine(logDir, string.Format("tmp_appReadable_log{0}.txt", Init.InstanceId));\r
+ int logFilePosition = 0;\r
\r
try\r
{\r
- // Make sure the application readable log file does not already exist. FileCopy fill fail if it does.\r
- if (File.Exists(logFile2))\r
- File.Delete(logFile2);\r
-\r
// Copy the log file.\r
if (File.Exists(logFile))\r
File.Copy(logFile, logFile2, true);\r
else\r
- {\r
- ResetLogReader();\r
return;\r
- }\r
-\r
- // Put the Query and User Generated Query Flag on the log.\r
- if (logFilePosition == 0 && job.Query != null)\r
- {\r
- logBuffer.AppendLine("### CLI Query: " + job.Query);\r
- logBuffer.AppendLine("### User Query: " + job.CustomQuery);\r
- logBuffer.AppendLine("#########################################");\r
- }\r
\r
// Start the Reader\r
// Only use text which continues on from the last read line\r
- StreamReader sr = new StreamReader(logFile2);\r
- string line;\r
- int i = 1;\r
- while ((line = sr.ReadLine()) != null)\r
+ using (StreamReader sr = new StreamReader(logFile2))\r
{\r
- if (i > logFilePosition)\r
+ string line;\r
+ int i = 1;\r
+ while ((line = sr.ReadLine()) != null)\r
{\r
- logBuffer.AppendLine(line);\r
- logFilePosition++;\r
+ if (i > logFilePosition)\r
+ {\r
+ logBuffer.AppendLine(line);\r
+ logFilePosition++;\r
+ }\r
+ i++;\r
}\r
- i++;\r
+ sr.Close();\r
}\r
- sr.Close();\r
- sr.Dispose();\r
}\r
- catch (Exception)\r
+ catch (Exception exc)\r
{\r
- ResetLogReader();\r
+ logBuffer.Append(\r
+ Environment.NewLine + "Unable to read Log file..." + Environment.NewLine + exc +\r
+ Environment.NewLine);\r
}\r
}\r
}\r
\r
/// <summary>\r
- /// Reset the Log Reader\r
+ /// Setup the logging.\r
/// </summary>\r
- private void ResetLogReader()\r
- {\r
- logFilePosition = 0;\r
- logBuffer = new StringBuilder();\r
- }\r
-\r
- /// <summary>\r
- /// Recieve the Standard Error information and process it\r
- /// </summary>\r
- /// <param name="sender">\r
- /// The Sender Object\r
+ /// <param name="encodeQueueTask">\r
+ /// The encode QueueTask.\r
/// </param>\r
- /// <param name="e">\r
- /// DataReceived EventArgs\r
- /// </param>\r
- private void HbProcErrorDataReceived(object sender, DataReceivedEventArgs e)\r
+ private void SetupLogging(QueueTask encodeQueueTask)\r
{\r
- if (!String.IsNullOrEmpty(e.Data))\r
+ string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
+ string logFile = Path.Combine(logDir, string.Format("last_encode_log{0}.txt", Init.InstanceId));\r
+ string logFile2 = Path.Combine(logDir, string.Format("tmp_appReadable_log{0}.txt", Init.InstanceId));\r
+\r
+ try\r
{\r
- lock (logBuffer)\r
- logBuffer.AppendLine(e.Data);\r
+ logBuffer = new StringBuilder();\r
+\r
+ // Clear the current Encode Logs\r
+ if (File.Exists(logFile)) File.Delete(logFile);\r
+ if (File.Exists(logFile2)) File.Delete(logFile2);\r
+\r
+ fileWriter = new StreamWriter(logFile) { AutoFlush = true };\r
+\r
+ fileWriter.WriteLine(UtilityService.CreateCliLogHeader(encodeQueueTask));\r
+ logBuffer.AppendLine(UtilityService.CreateCliLogHeader(encodeQueueTask));\r
+ }\r
+ catch (Exception)\r
+ {\r
+ if (fileWriter != null)\r
+ {\r
+ fileWriter.Close();\r
+ fileWriter.Dispose();\r
+ }\r
+ throw;\r
}\r
}\r
\r
/// <summary>\r
- /// Standard Input Data Recieved from the CLI\r
+ /// Recieve the Standard Error information and process it\r
/// </summary>\r
/// <param name="sender">\r
/// The Sender Object\r
/// <param name="e">\r
/// DataReceived EventArgs\r
/// </param>\r
- private void HbProcOutputDataReceived(object sender, DataReceivedEventArgs e)\r
+ private void HbProcErrorDataReceived(object sender, DataReceivedEventArgs e)\r
{\r
if (!String.IsNullOrEmpty(e.Data))\r
{\r
- lock (logBuffer)\r
- logBuffer.AppendLine(e.Data);\r
+ try\r
+ {\r
+ lock (logBuffer)\r
+ logBuffer.AppendLine(e.Data);\r
+\r
+ lock (fileWriterLock)\r
+ {\r
+ if (fileWriter != null && fileWriter.BaseStream.CanWrite)\r
+ {\r
+ fileWriter.WriteLine(e.Data);\r
+\r
+ // If the logging grows past 100MB, kill the encode and stop.\r
+ if (fileWriter.BaseStream.Length > 100000000)\r
+ {\r
+ this.Stop(\r
+ new Exception(\r
+ "The encode has been stopped. The log file has grown to over 100MB which indicates a serious problem has occured with the encode." +\r
+ "Please check the encode log for an indication of what the problem is."));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ // Do Nothing.\r
+ }\r
}\r
}\r
\r
/// <param name="e">\r
/// The EventArgs.\r
/// </param>\r
- private void Encode_EncodeStarted(object sender, EventArgs e)\r
+ private void EncodeEncodeStarted(object sender, EventArgs e)\r
{\r
Thread monitor = new Thread(EncodeMonitor);\r
monitor.Start();\r
}\r
\r
/// <summary>\r
- /// Monitor the Job\r
+ /// Monitor the QueueTask\r
/// </summary>\r
private void EncodeMonitor()\r
{\r
encode.OnEncodeProgress += EncodeOnEncodeProgress;\r
while (!encode.EndOfStream)\r
encode.ReadEncodeStatus();\r
-\r
- // Main.ShowExceptiowWindow("Encode Monitor Stopped", "Stopped");\r
}\r
catch (Exception exc)\r
{\r
- Main.ShowExceptiowWindow("An Unknown Error has occured", exc.ToString());\r
+ EncodeOnEncodeProgress(null, 0, 0, 0, 0, 0, "Unknown, status not available..");\r
}\r
}\r
\r
/// <param name="currentFps">Current encode speed in fps</param>\r
/// <param name="avg">Avg encode speed</param>\r
/// <param name="timeRemaining">Time Left</param>\r
- private void EncodeOnEncodeProgress(object sender, int currentTask, int taskCount, float percentComplete, float currentFps, float avg, TimeSpan timeRemaining)\r
+ private void EncodeOnEncodeProgress(object sender, int currentTask, int taskCount, float percentComplete, float currentFps, float avg, string timeRemaining)\r
{\r
EncodeProgressEventArgs eventArgs = new EncodeProgressEventArgs\r
- {\r
- AverageFrameRate = avg,\r
- CurrentFrameRate = currentFps,\r
- EstimatedTimeLeft = timeRemaining,\r
- PercentComplete = percentComplete,\r
- Task = currentTask,\r
- TaskCount = taskCount\r
- };\r
+ {\r
+ AverageFrameRate = avg,\r
+ CurrentFrameRate = currentFps,\r
+ EstimatedTimeLeft = Converters.EncodeToTimespan(timeRemaining),\r
+ PercentComplete = percentComplete,\r
+ Task = currentTask,\r
+ TaskCount = taskCount\r
+ };\r
\r
if (this.EncodeStatusChanged != null)\r
this.EncodeStatusChanged(this, eventArgs);\r
windowsSeven.SetTaskBarProgress(percent);\r
}\r
}\r
+\r
+ #endregion\r
}\r
}
\ No newline at end of file