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
6 namespace Handbrake.Services
\r
9 using System.Diagnostics;
\r
12 using System.Threading;
\r
13 using System.Windows.Forms;
\r
19 public class ScanService
\r
21 /* Private Variables */
\r
26 private static readonly object locker = new object();
\r
29 /// The CLI data parser
\r
31 private Parser readData;
\r
36 private StringBuilder logBuffer;
\r
39 /// The line number thats been read to in the log file
\r
41 private int logFilePosition;
\r
44 /// The Process belonging to the CLI
\r
46 private Process hbProc;
\r
48 /* Event Handlers */
\r
51 /// Scan has Started
\r
53 public event EventHandler ScanStared;
\r
56 /// Scan has completed
\r
58 public event EventHandler ScanCompleted;
\r
61 /// Scan process has changed to a new title
\r
63 public event EventHandler ScanStatusChanged;
\r
68 /// Gets a value indicating whether IsScanning.
\r
70 public bool IsScanning { get; private set; }
\r
73 /// Gets the Scan Status.
\r
75 public string ScanStatus { get; private set; }
\r
78 /// Gets the Souce Data.
\r
80 public DVD SouceData { get; private set; }
\r
83 /// Gets ActivityLog.
\r
85 public string ActivityLog
\r
90 return readData.Buffer.ToString();
\r
92 if (logBuffer == null)
\r
95 ReadLastScanFile();
\r
98 return logBuffer != null ? logBuffer.ToString() : string.Empty;
\r
102 /* Public Methods */
\r
105 /// Scan a Source Path.
\r
106 /// Title 0: scan all
\r
108 /// <param name="sourcePath">Path to the file to scan</param>
\r
109 /// <param name="title">int title number. 0 for scan all</param>
\r
110 public void Scan(string sourcePath, int title)
\r
112 Thread t = new Thread(unused => this.ScanSource(sourcePath, title));
\r
123 if (hbProc != null)
\r
126 catch (Exception ex)
\r
129 "Unable to kill HandBrakeCLI.exe \nYou may need to manually kill HandBrakeCLI.exe using the Windows Task Manager if it does not close automatically within the next few minutes. \n\nError Information: \n" +
\r
130 ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r
134 /* Private Methods */
\r
137 /// Start a scan for a given source path and title
\r
139 /// <param name="sourcePath">Path to the source file</param>
\r
140 /// <param name="title">the title number to look at</param>
\r
141 private void ScanSource(object sourcePath, int title)
\r
146 if (this.ScanStared != null)
\r
147 this.ScanStared(this, new EventArgs());
\r
151 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");
\r
152 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
\r
153 "\\HandBrake\\logs";
\r
154 string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt");
\r
156 // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file)
\r
157 if (File.Exists(dvdInfoPath))
\r
158 File.Delete(dvdInfoPath);
\r
160 string extraArguments = string.Empty;
\r
161 if (Properties.Settings.Default.noDvdNav)
\r
162 extraArguments = " --no-dvdnav";
\r
165 extraArguments += " --scan ";
\r
167 this.hbProc = new Process
\r
171 FileName = handbrakeCLIPath,
\r
173 String.Format(@" -i ""{0}"" -t{1} {2} -v ", sourcePath, title,
\r
175 RedirectStandardOutput = true,
\r
176 RedirectStandardError = true,
\r
177 UseShellExecute = false,
\r
178 CreateNoWindow = true
\r
183 this.hbProc.Start();
\r
185 this.readData = new Parser(this.hbProc.StandardError.BaseStream);
\r
186 this.readData.OnScanProgress += new ScanProgressEventHandler(this.OnScanProgress);
\r
187 this.SouceData = DVD.Parse(this.readData);
\r
189 // Write the Buffer out to file.
\r
190 StreamWriter scanLog = new StreamWriter(dvdInfoPath);
\r
191 scanLog.Write(this.readData.Buffer);
\r
194 logBuffer = readData.Buffer;
\r
196 IsScanning = false;
\r
198 if (this.ScanCompleted != null)
\r
199 this.ScanCompleted(this, new EventArgs());
\r
201 catch (Exception exc)
\r
203 frmExceptionWindow exceptionWindow = new frmExceptionWindow();
\r
204 exceptionWindow.Setup("frmMain.cs - scanProcess() Error", exc.ToString());
\r
205 exceptionWindow.ShowDialog();
\r
210 /// Read the log file
\r
212 private void ReadLastScanFile()
\r
216 // 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
217 // we'll need to make a copy of it.
\r
218 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
\r
219 "\\HandBrake\\logs";
\r
220 string logFile = Path.Combine(logDir, "last_scan_log.txt");
\r
221 string logFile2 = Path.Combine(logDir, "tmp_appReadable_log.txt");
\r
225 // Make sure the application readable log file does not already exist. FileCopy fill fail if it does.
\r
226 if (File.Exists(logFile2))
\r
227 File.Delete(logFile2);
\r
229 // Copy the log file.
\r
230 if (File.Exists(logFile))
\r
231 File.Copy(logFile, logFile2, true);
\r
238 // Start the Reader
\r
239 // Only use text which continues on from the last read line
\r
240 StreamReader sr = new StreamReader(logFile2);
\r
243 while ((line = sr.ReadLine()) != null)
\r
245 if (i > logFilePosition)
\r
247 logBuffer.AppendLine(line);
\r
255 catch (Exception exc)
\r
257 Console.WriteLine(exc.ToString());
\r
264 /// Reset the Log Reader
\r
266 private void ResetLogReader()
\r
268 logFilePosition = 0;
\r
269 logBuffer = new StringBuilder();
\r
273 /// Fire an event when the scan process progresses
\r
275 /// <param name="sender">the sender</param>
\r
276 /// <param name="currentTitle">the current title being scanned</param>
\r
277 /// <param name="titleCount">the total number of titles</param>
\r
278 private void OnScanProgress(object sender, int currentTitle, int titleCount)
\r
280 this.ScanStatus = string.Format("Processing Title: {0} of {1}", currentTitle, titleCount);
\r
281 if (this.ScanStatusChanged != null)
\r
282 this.ScanStatusChanged(this, new EventArgs());
\r