From 34eb1d1a7a02b3bf976b094cbfab3cab10724b37 Mon Sep 17 00:00:00 2001 From: sr55 Date: Sat, 27 Feb 2010 22:20:14 +0000 Subject: [PATCH] WinGui: - Checkin some missing files. git-svn-id: svn://localhost/HandBrake/trunk@3145 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- win/C#/Services/Encode.cs | 537 ++++++++++++++++++++++++++++++++++++++++++++++ win/C#/Services/Queue.cs | 387 +++++++++++++++++++++++++++++++++ win/C#/Services/Scan.cs | 265 +++++++++++++++++++++++ 3 files changed, 1189 insertions(+) create mode 100644 win/C#/Services/Encode.cs create mode 100644 win/C#/Services/Queue.cs create mode 100644 win/C#/Services/Scan.cs diff --git a/win/C#/Services/Encode.cs b/win/C#/Services/Encode.cs new file mode 100644 index 00000000..d73a4a6e --- /dev/null +++ b/win/C#/Services/Encode.cs @@ -0,0 +1,537 @@ +/* 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. */ + + +namespace Handbrake.Services +{ + using System; + using System.Diagnostics; + using System.IO; + using System.Text; + using System.Threading; + using System.Windows.Forms; + using Functions; + using Model; + using Properties; + using Timer = System.Threading.Timer; + + /// + /// Class which handles the CLI + /// + public class Encode + { + /// + /// An Encode Job + /// + private Job job; + + /// + /// The Log Buffer + /// + private StringBuilder logBuffer; + + /// + /// The line number thats been read to in the log file + /// + private int logFilePosition; + + /// + /// A Timer for this window + /// + private Timer windowTimer; + + /// + /// Fires when a new CLI Job starts + /// + public event EventHandler EncodeStarted; + + /// + /// Fires when a CLI job finishes. + /// + public event EventHandler EncodeEnded; + + /// + /// Gets or sets The HB Process + /// + public Process HbProcess { get; set; } + + /// + /// Gets or sets The Process Handle + /// + public IntPtr ProcessHandle { get; set; } + + /// + /// Gets or sets a value indicating whether HandBrakeCLI.exe is running + /// + public bool IsEncoding { get; set; } + + /// + /// Gets or sets the Process ID + /// + public int ProcessID { get; set; } + + /// + /// Gets ActivityLog. + /// + public string ActivityLog + { + get + { + if (logBuffer != null) + return logBuffer.ToString(); + + return string.Empty; + } + } + + /// + /// Create a preview sample video + /// + /// + /// The CLI Query + /// + public void CreatePreviewSample(string query) + { + Job job = new Job {Query = query}; + this.Run(job); + } + + /// + /// Kill the CLI process + /// + public void Stop() + { + if (this.HbProcess != null) + this.HbProcess.Kill(); + + Process[] list = Process.GetProcessesByName("HandBrakeCLI"); + foreach (Process process in list) + process.Kill(); + + if (this.EncodeEnded != null) + this.EncodeEnded(this, new EventArgs()); + + IsEncoding = false; + } + + /// + /// Attempt to Safely kill a DirectRun() CLI + /// NOTE: This will not work with a MinGW CLI + /// Note: http://www.cygwin.com/ml/cygwin/2006-03/msg00330.html + /// + public void SafelyClose() + { + if ((int)this.ProcessHandle == 0) + return; + + // Allow the CLI to exit cleanly + Win32.SetForegroundWindow((int)this.ProcessHandle); + SendKeys.Send("^C"); + SendKeys.Flush(); + + // HbProcess.StandardInput.AutoFlush = true; + // HbProcess.StandardInput.WriteLine("^C"); + + IsEncoding = false; + } + + /// + /// Execute a HandBrakeCLI process. + /// + /// + /// The enc Job. + /// + protected void Run(Job encJob) + { + this.job = encJob; + try + { + if (this.EncodeStarted != null) + this.EncodeStarted(this, new EventArgs()); + + IsEncoding = true; + + ResetLogReader(); + + string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe"); + string logPath = + Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs", + "last_encode_log.txt"); + string strCmdLine = String.Format(@" /C """"{0}"" {1} 2>""{2}"" """, handbrakeCLIPath, encJob.Query, logPath); + var cliStart = new ProcessStartInfo("CMD.exe", strCmdLine); + + if (Settings.Default.enocdeStatusInGui) + { + cliStart.RedirectStandardOutput = true; + cliStart.UseShellExecute = false; + if (!Settings.Default.showCliForInGuiEncodeStatus) + cliStart.CreateNoWindow = true; + } + if (Settings.Default.cli_minimized) + cliStart.WindowStyle = ProcessWindowStyle.Minimized; + + Process[] before = Process.GetProcesses(); // Get a list of running processes before starting. + this.HbProcess = Process.Start(cliStart); + this.ProcessID = Main.GetCliProcess(before); + + + if (this.HbProcess != null) + this.ProcessHandle = this.HbProcess.MainWindowHandle; // Set the process Handle + + // Start the Log Monitor + windowTimer = new Timer(new TimerCallback(ReadFile), null, 1000, 1000); + + // Set the process Priority + Process hbCliProcess = null; + if (this.ProcessID != -1) + hbCliProcess = Process.GetProcessById(this.ProcessID); + + if (hbCliProcess != null) + switch (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( + "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" + + exc, + "Error", + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + + /// + /// Function to run the CLI directly rather than via CMD + /// TODO: Code to handle the Log data has yet to be written. + /// TODO: Code to handle the % / ETA info has to be written. + /// + /// + /// The query. + /// + protected void DirectRun(string query) + { + try + { + if (this.EncodeStarted != null) + this.EncodeStarted(this, new EventArgs()); + + IsEncoding = true; + ResetLogReader(); + + // Setup the job + string handbrakeCLIPath = Path.Combine(Environment.CurrentDirectory, "HandBrakeCLI.exe"); + HbProcess = new Process + { + StartInfo = + { + FileName = handbrakeCLIPath, + Arguments = query, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + RedirectStandardInput = true, + CreateNoWindow = false, + WindowStyle = ProcessWindowStyle.Minimized + } + }; + + // Setup event handlers for rediected data + HbProcess.ErrorDataReceived += new DataReceivedEventHandler(HbProcErrorDataReceived); + HbProcess.OutputDataReceived += new DataReceivedEventHandler(HbProcOutputDataReceived); + + // Start the process + HbProcess.Start(); + + // Setup the asynchronous reading of stdin and stderr + HbProcess.BeginErrorReadLine(); + HbProcess.BeginOutputReadLine(); + + // Set the Process Priority); + switch (Settings.Default.processPriority) + { + case "Realtime": + HbProcess.PriorityClass = ProcessPriorityClass.RealTime; + break; + case "High": + HbProcess.PriorityClass = ProcessPriorityClass.High; + break; + case "Above Normal": + HbProcess.PriorityClass = ProcessPriorityClass.AboveNormal; + break; + case "Normal": + HbProcess.PriorityClass = ProcessPriorityClass.Normal; + break; + case "Low": + HbProcess.PriorityClass = ProcessPriorityClass.Idle; + break; + default: + HbProcess.PriorityClass = ProcessPriorityClass.BelowNormal; + break; + } + + // Set the class items + this.ProcessID = HbProcess.Id; + this.ProcessHandle = HbProcess.Handle; + } + catch (Exception exc) + { + Console.WriteLine(exc); + } + } + + /// + /// Perform an action after an encode. e.g a shutdown, standby, restart etc. + /// + protected void Finish() + { + if (this.EncodeEnded != null) + this.EncodeEnded(this, new EventArgs()); + + IsEncoding = false; + + if (!IsEncoding) + { + windowTimer.Dispose(); + ReadFile(null); + } + + // Growl + if (Settings.Default.growlQueue) + GrowlCommunicator.Notify("Queue Completed", "Put down that cocktail...\nyour Handbrake queue is done."); + + // Do something whent he encode ends. + switch (Settings.Default.CompletionOption) + { + case "Shutdown": + Process.Start("Shutdown", "-s -t 60"); + break; + case "Log Off": + Win32.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": + Win32.LockWorkStation(); + break; + case "Quit HandBrake": + Application.Exit(); + break; + default: + break; + } + } + + /// + /// Add the CLI Query to the Log File. + /// + /// + /// The Encode Job Object + /// + protected void AddCLIQueryToLog(Job encJob) + { + try + { + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + string logPath = Path.Combine(logDir, "last_encode_log.txt"); + + var reader = new StreamReader(File.Open(logPath, FileMode.Open, FileAccess.Read, FileShare.Read)); + string log = reader.ReadToEnd(); + reader.Close(); + + var writer = new StreamWriter(File.Create(logPath)); + + writer.WriteLine("### CLI Query: " + encJob.Query); + writer.WriteLine("### User Query: " + encJob.CustomQuery); + writer.WriteLine("#########################################"); + writer.WriteLine(log); + writer.Flush(); + writer.Close(); + } + catch (Exception) + { + return; + } + } + + /// + /// Save a copy of the log to the users desired location or a default location + /// if this feature is enabled in options. + /// + /// + /// The Destination File Path + /// + protected 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 destinationFile = Path.GetFileName(destination); + string encodeLogFile = destinationFile + " " + + DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + ".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 (Settings.Default.saveLogWithVideo) + File.Copy(tempLogFile, Path.Combine(encodeDestinationPath, encodeLogFile)); + + // Save a copy of the log file to a user specified location + if (Directory.Exists(Settings.Default.saveLogPath)) + if (Settings.Default.saveLogPath != String.Empty && Settings.Default.saveLogToSpecifiedPath) + File.Copy(tempLogFile, Path.Combine(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); + } + } + + /// + /// Read the log file + /// + /// + /// The object. + /// + private void ReadFile(object n) + { + lock (logBuffer) + { + // 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), + // we'll need to make a copy of it. + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + string logFile = Path.Combine(logDir, "last_encode_log.txt"); + string logFile2 = Path.Combine(logDir, "tmp_appReadable_log.txt"); + + try + { + // Make sure the application readable log file does not already exist. FileCopy fill fail if it does. + if (File.Exists(logFile2)) + File.Delete(logFile2); + + // Copy the log file. + if (File.Exists(logFile)) + File.Copy(logFile, logFile2, true); + else + { + ResetLogReader(); + return; + } + + // Put the Query and User Generated Query Flag on the log. + if (logFilePosition == 0) + { + logBuffer.AppendLine("### CLI Query: " + job.Query); + logBuffer.AppendLine("### User Query: " + job.CustomQuery); + logBuffer.AppendLine("#########################################"); + } + + // Start the Reader + // Only use text which continues on from the last read line + StreamReader sr = new StreamReader(logFile2); + string line; + int i = 1; + while ((line = sr.ReadLine()) != null) + { + if (i > logFilePosition) + { + logBuffer.AppendLine(line); + logFilePosition++; + } + i++; + } + sr.Close(); + sr.Dispose(); + } + catch (Exception) + { + ResetLogReader(); + } + } + } + + /// + /// Reset the Log Reader + /// + private void ResetLogReader() + { + logFilePosition = 0; + logBuffer = new StringBuilder(); + } + + /// + /// Recieve the Standard Error information and process it + /// + /// + /// The Sender Object + /// + /// + /// DataReceived EventArgs + /// + private void HbProcErrorDataReceived(object sender, DataReceivedEventArgs e) + { + if (!String.IsNullOrEmpty(e.Data)) + { + lock (logBuffer) + logBuffer.AppendLine(e.Data); + } + } + + /// + /// Standard Input Data Recieved from the CLI + /// + /// + /// The Sender Object + /// + /// + /// DataReceived EventArgs + /// + private void HbProcOutputDataReceived(object sender, DataReceivedEventArgs e) + { + if (!String.IsNullOrEmpty(e.Data)) + { + lock (logBuffer) + logBuffer.AppendLine(e.Data); + } + } + } +} \ No newline at end of file diff --git a/win/C#/Services/Queue.cs b/win/C#/Services/Queue.cs new file mode 100644 index 00000000..59b1437d --- /dev/null +++ b/win/C#/Services/Queue.cs @@ -0,0 +1,387 @@ +/* Queue.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.Services +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.IO; + using System.Threading; + using System.Windows.Forms; + using System.Xml.Serialization; + using Functions; + using Model; + + /// + /// The HandBrake Queue + /// + public class Queue : Encode + { + /// + /// An XML Serializer + /// + private static XmlSerializer serializer; + + /// + /// The Queue Job List + /// + private readonly List queue = new List(); + + /// + /// The Next Job ID + /// + private int nextJobId; + + /// + /// Fires when a pause to the encode queue has been requested. + /// + public event EventHandler QueuePauseRequested; + + /// + /// Fires when the entire encode queue has completed. + /// + public event EventHandler QueueCompleted; + + #region Queue + + /// + /// Gets and removes the next job in the queue. + /// + /// The job that was removed from the queue. + private Job GetNextJob() + { + Job job = this.queue[0]; + this.LastEncode = job; + this.Remove(0); // Remove the item which we are about to pass out. + + this.WriteQueueStateToFile("hb_queue_recovery.xml"); + + return job; + } + + /// + /// Gets the current state of the encode queue. + /// + public ReadOnlyCollection CurrentQueue + { + get { return this.queue.AsReadOnly(); } + } + + /// + /// Gets the number of items in the queue. + /// + public int Count + { + get { return this.queue.Count; } + } + + /// + /// Adds an item to the queue. + /// + /// + /// The query that will be passed to the HandBrake CLI. + /// + /// + /// The location of the source video. + /// + /// + /// The location where the encoded video will be. + /// + /// + /// Custom job + /// + public void Add(string query, string source, string destination, bool customJob) + { + Job newJob = new Job + { + Id = this.nextJobId++, + Query = query, + Source = source, + Destination = destination, + CustomQuery = customJob + }; + + this.queue.Add(newJob); + this.WriteQueueStateToFile("hb_queue_recovery.xml"); + } + + /// + /// Removes an item from the queue. + /// + /// The zero-based location of the job in the queue. + public void Remove(int index) + { + this.queue.RemoveAt(index); + this.WriteQueueStateToFile("hb_queue_recovery.xml"); + } + + /// + /// Retrieve a job from the queue + /// + /// the job id + /// A job for the given index or blank job object + public Job GetJob(int index) + { + if (this.queue.Count >= (index + 1)) + return this.queue[index]; + + return new Job(); + } + + /// + /// Moves an item up one position in the queue. + /// + /// The zero-based location of the job in the queue. + public void MoveUp(int index) + { + if (index > 0) + { + Job item = queue[index]; + + queue.RemoveAt(index); + queue.Insert((index - 1), item); + } + + WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file + } + + /// + /// Moves an item down one position in the queue. + /// + /// The zero-based location of the job in the queue. + public void MoveDown(int index) + { + if (index < this.queue.Count - 1) + { + Job item = this.queue[index]; + + this.queue.RemoveAt(index); + this.queue.Insert((index + 1), item); + } + + this.WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file + } + + /// + /// Writes the current state of the queue to a file. + /// + /// The location of the file to write the queue to. + public void WriteQueueStateToFile(string file) + { + string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + @"HandBrake\hb_queue_recovery.xml"); + string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file; + + try + { + using (FileStream strm = new FileStream(tempPath, FileMode.Create, FileAccess.Write)) + { + if (serializer == null) + serializer = new XmlSerializer(typeof (List)); + serializer.Serialize(strm, queue); + strm.Close(); + strm.Dispose(); + } + } + catch (Exception) + { + return; + } + } + + /// + /// Writes the current state of the queue in the form of a batch (.bat) file. + /// + /// The location of the file to write the batch file to. + public void WriteBatchScriptToFile(string file) + { + string queries = string.Empty; + foreach (Job queueItem in this.queue) + { + string qItem = queueItem.Query; + string fullQuery = '"' + Application.StartupPath + "\\HandBrakeCLI.exe" + '"' + qItem; + + if (queries == string.Empty) + queries = queries + fullQuery; + else + queries = queries + " && " + fullQuery; + } + string strCmdLine = queries; + + if (file != string.Empty) + { + try + { + // Create a StreamWriter and open the file, Write the batch file query to the file and + // Close the stream + using (StreamWriter line = new StreamWriter(file)) + { + line.WriteLine(strCmdLine); + } + + 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); + } + } + } + + /// + /// Reads a serialized XML file that represents a queue of encoding jobs. + /// + /// The location of the file to read the queue from. + public void LoadQueueFromFile(string file) + { + string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + @"HandBrake\hb_queue_recovery.xml"); + string tempPath = file == "hb_queue_recovery.xml" ? appDataPath : file; + + if (File.Exists(tempPath)) + { + using (FileStream strm = new FileStream(tempPath, FileMode.Open, FileAccess.Read)) + { + if (strm.Length != 0) + { + if (serializer == null) + serializer = new XmlSerializer(typeof (List)); + + List list = serializer.Deserialize(strm) as List; + + if (list != null) + foreach (Job item in list) + this.queue.Add(item); + + if (file != "hb_queue_recovery.xml") + this.WriteQueueStateToFile("hb_queue_recovery.xml"); + } + } + } + } + + /// + /// Checks the current queue for an existing instance of the specified destination. + /// + /// The destination of the encode. + /// Whether or not the supplied destination is already in the queue. + public bool CheckForDestinationDuplicate(string destination) + { + foreach (Job checkItem in this.queue) + { + if (checkItem.Destination.Contains(destination.Replace("\\\\", "\\"))) + return true; + } + + return false; + } + + #endregion + + #region Encoding + + /// + /// Gets or sets the last encode that was processed. + /// + /// + public Job LastEncode { get; set; } + + /// + /// Gets a value indicating whether Request Pause + /// + public bool PauseRequested { get; private set; } + + /// + /// Starts encoding the first job in the queue and continues encoding until all jobs + /// have been encoded. + /// + public void Start() + { + if (this.Count != 0) + { + if (this.PauseRequested) + this.PauseRequested = false; + else + { + this.PauseRequested = false; + try + { + Thread theQueue = new Thread(this.StartQueue) {IsBackground = true}; + theQueue.Start(); + } + catch (Exception exc) + { + MessageBox.Show(exc.ToString()); + } + } + } + } + + /// + /// Requests a pause of the encode queue. + /// + public void Pause() + { + this.PauseRequested = true; + + if (this.QueuePauseRequested != null) + this.QueuePauseRequested(this, new EventArgs()); + } + + /// + /// Run through all the jobs on the queue. + /// + /// Object State + private void StartQueue(object state) + { + // Run through each item on the queue + while (this.Count != 0) + { + Job encJob = this.GetNextJob(); + this.WriteQueueStateToFile("hb_queue_recovery.xml"); // Update the queue recovery file + + Run(encJob); + + if (HbProcess == null) + { + return; + } + HbProcess.WaitForExit(); + + AddCLIQueryToLog(encJob); + this.CopyLog(this.LastEncode.Destination); + + HbProcess.Close(); + HbProcess.Dispose(); + + IsEncoding = false; + + // Growl + if (Properties.Settings.Default.growlEncode) + GrowlCommunicator.Notify("Encode Completed", + "Put down that cocktail...\nyour Handbrake encode is done."); + + while (this.PauseRequested) // Need to find a better way of doing this. + { + Thread.Sleep(2000); + } + } + this.LastEncode = new Job(); + + if (this.QueueCompleted != null) + this.QueueCompleted(this, new EventArgs()); + + // After the encode is done, we may want to shutdown, suspend etc. + Finish(); + } + + #endregion + } +} \ No newline at end of file diff --git a/win/C#/Services/Scan.cs b/win/C#/Services/Scan.cs new file mode 100644 index 00000000..aae87a0d --- /dev/null +++ b/win/C#/Services/Scan.cs @@ -0,0 +1,265 @@ +/* Scan.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.Services +{ + using System; + using System.Diagnostics; + using System.IO; + using System.Text; + using System.Threading; + using System.Windows.Forms; + using Parsing; + + /// + /// Scan a Source + /// + public class Scan + { + /// + /// The information for this source + /// + private DVD thisDvd; + + /// + /// The CLI data parser + /// + private Parser readData; + + /// + /// The Log Buffer + /// + private StringBuilder logBuffer; + + static object locker = new object(); + + /// + /// The line number thats been read to in the log file + /// + private int logFilePosition; + + /// + /// The Process belonging to the CLI + /// + private Process hbProc; + + /// + /// The Progress of the scan + /// + private string scanProgress; + + /// + /// Scan has Started + /// + public event EventHandler ScanStared; + + /// + /// Scan has completed + /// + public event EventHandler ScanCompleted; + + /// + /// Scan process has changed to a new title + /// + public event EventHandler ScanStatusChanged; + + /// + /// Gets or sets a value indicating whether IsScanning. + /// + public bool IsScanning { get; set; } + + /// + /// Gets ActivityLog. + /// + public string ActivityLog + { + get + { + if (IsScanning) + return readData.Buffer; + + ReadFile(); + return logBuffer.ToString(); + } + } + + /// + /// Scan a Source Path. + /// Title 0: scan all + /// + /// Path to the file to scan + /// int title number. 0 for scan all + public void ScanSource(string sourcePath, int title) + { + Thread t = new Thread(unused => this.RunScan(sourcePath, title)); + t.Start(); + } + + /// + /// Object containing the information parsed in the scan. + /// + /// The DVD object containing the scan information + public DVD SouceData() + { + return this.thisDvd; + } + + /// + /// Progress of the scan. + /// + /// The progress of the scan + public string ScanStatus() + { + return this.scanProgress; + } + + /// + /// The Scan Process + /// + /// The CLI process + public Process ScanProcess() + { + return this.hbProc; + } + + /// + /// Start a scan for a given source path and title + /// + /// Path to the source file + /// the title number to look at + private void RunScan(object sourcePath, int title) + { + try + { + IsScanning = true; + if (this.ScanStared != null) + this.ScanStared(this, new EventArgs()); + + ResetLogReader(); + + string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe"); + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt"); + + // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file) + if (File.Exists(dvdInfoPath)) + File.Delete(dvdInfoPath); + + string dvdnav = string.Empty; + if (Properties.Settings.Default.noDvdNav) + dvdnav = " --no-dvdnav"; + + this.hbProc = new Process + { + StartInfo = + { + FileName = handbrakeCLIPath, + Arguments = + String.Format(@" -i ""{0}"" -t{1} {2} -v ", sourcePath, title, dvdnav), + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + } + }; + + // Start the Scan + this.hbProc.Start(); + + this.readData = new Parser(this.hbProc.StandardError.BaseStream); + this.readData.OnScanProgress += new ScanProgressEventHandler(this.OnScanProgress); + this.thisDvd = DVD.Parse(this.readData); + + // Write the Buffer out to file. + StreamWriter scanLog = new StreamWriter(dvdInfoPath); + scanLog.Write(this.readData.Buffer); + scanLog.Flush(); + scanLog.Close(); + + if (this.ScanCompleted != null) + this.ScanCompleted(this, new EventArgs()); + IsScanning = false; + } + catch (Exception exc) + { + Console.WriteLine("frmMain.cs - scanProcess() " + exc); + } + } + + /// + /// Read the log file + /// + private void ReadFile() + { + lock (locker) + { + // 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), + // we'll need to make a copy of it. + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + string logFile = Path.Combine(logDir, "last_scan_log.txt"); + string logFile2 = Path.Combine(logDir, "tmp_appReadable_log.txt"); + + try + { + // Make sure the application readable log file does not already exist. FileCopy fill fail if it does. + if (File.Exists(logFile2)) + File.Delete(logFile2); + + // Copy the log file. + if (File.Exists(logFile)) + File.Copy(logFile, logFile2, true); + else + { + ResetLogReader(); + return; + } + + // Start the Reader + // Only use text which continues on from the last read line + StreamReader sr = new StreamReader(logFile2); + string line; + int i = 1; + while ((line = sr.ReadLine()) != null) + { + if (i > logFilePosition) + { + logBuffer.AppendLine(line); + logFilePosition++; + } + i++; + } + sr.Close(); + sr.Dispose(); + } + catch (Exception) + { + ResetLogReader(); + } + } + } + + /// + /// Reset the Log Reader + /// + private void ResetLogReader() + { + logFilePosition = 0; + logBuffer = new StringBuilder(); + } + + /// + /// Fire an event when the scan process progresses + /// + /// the sender + /// the current title being scanned + /// the total number of titles + private void OnScanProgress(object sender, int currentTitle, int titleCount) + { + this.scanProgress = string.Format("Processing Title: {0} of {1}", currentTitle, titleCount); + if (this.ScanStatusChanged != null) + this.ScanStatusChanged(this, new EventArgs()); + } + } +} \ No newline at end of file -- 2.11.0