OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Services / Scan.cs
1 /*  Scan.cs $\r
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
5 \r
6 namespace Handbrake.Services\r
7 {\r
8     using System;\r
9     using System.Diagnostics;\r
10     using System.IO;\r
11     using System.Text;\r
12     using System.Threading;\r
13     using System.Windows.Forms;\r
14     using Parsing;\r
15 \r
16     /// <summary>\r
17     /// Scan a Source\r
18     /// </summary>\r
19     public class Scan\r
20     {\r
21         /// <summary>\r
22         /// The information for this source\r
23         /// </summary>\r
24         private DVD thisDvd;\r
25 \r
26         /// <summary>\r
27         /// The CLI data parser\r
28         /// </summary>\r
29         private Parser readData;\r
30 \r
31         /// <summary>\r
32         /// The Log Buffer\r
33         /// </summary>\r
34         private StringBuilder logBuffer;\r
35 \r
36         /// <summary>\r
37         /// A Lock object\r
38         /// </summary>\r
39         private static object locker = new object();\r
40 \r
41         /// <summary>\r
42         /// The line number thats been read to in the log file\r
43         /// </summary>\r
44         private int logFilePosition;\r
45 \r
46         /// <summary>\r
47         /// The Process belonging to the CLI\r
48         /// </summary>\r
49         private Process hbProc;\r
50 \r
51         /// <summary>\r
52         /// The Progress of the scan\r
53         /// </summary>\r
54         private string scanProgress;\r
55 \r
56         /// <summary>\r
57         /// Scan has Started\r
58         /// </summary>\r
59         public event EventHandler ScanStared;\r
60 \r
61         /// <summary>\r
62         /// Scan has completed\r
63         /// </summary>\r
64         public event EventHandler ScanCompleted;\r
65 \r
66         /// <summary>\r
67         /// Scan process has changed to a new title\r
68         /// </summary>\r
69         public event EventHandler ScanStatusChanged;\r
70 \r
71         /// <summary>\r
72         /// Gets or sets a value indicating whether IsScanning.\r
73         /// </summary>\r
74         public bool IsScanning { get; set; }\r
75 \r
76         /// <summary>\r
77         /// Gets ActivityLog.\r
78         /// </summary>\r
79         public string ActivityLog\r
80         {\r
81             get\r
82             {\r
83                 if (IsScanning)\r
84                     return readData.Buffer;\r
85 \r
86                 ReadFile();\r
87                 return logBuffer.ToString();\r
88             }\r
89         }\r
90 \r
91         /// <summary>\r
92         /// Scan a Source Path.\r
93         /// Title 0: scan all\r
94         /// </summary>\r
95         /// <param name="sourcePath">Path to the file to scan</param>\r
96         /// <param name="title">int title number. 0 for scan all</param>\r
97         public void ScanSource(string sourcePath, int title)\r
98         {\r
99             Thread t = new Thread(unused => this.RunScan(sourcePath, title));\r
100             t.Start();\r
101         }\r
102 \r
103         /// <summary>\r
104         /// Object containing the information parsed in the scan.\r
105         /// </summary>\r
106         /// <returns>The DVD object containing the scan information</returns>\r
107         public DVD SouceData()\r
108         {\r
109             return this.thisDvd;\r
110         }\r
111 \r
112         /// <summary>\r
113         /// Progress of the scan.\r
114         /// </summary>\r
115         /// <returns>The progress of the scan</returns>\r
116         public string ScanStatus()\r
117         {\r
118             return this.scanProgress;\r
119         }\r
120 \r
121         /// <summary>\r
122         /// The Scan Process\r
123         /// </summary>\r
124         /// <returns>The CLI process</returns>\r
125         public Process ScanProcess()\r
126         {\r
127             return this.hbProc;\r
128         }\r
129 \r
130         /// <summary>\r
131         /// Kill the scan\r
132         /// </summary>\r
133         public void KillScan()\r
134         {\r
135             try\r
136             {\r
137                 if (hbProc != null)\r
138                     hbProc.Kill();\r
139             }\r
140             catch (Exception ex)\r
141             {\r
142                 MessageBox.Show(\r
143                     "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
144                     ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
145             }\r
146         }\r
147 \r
148         /// <summary>\r
149         /// Start a scan for a given source path and title\r
150         /// </summary>\r
151         /// <param name="sourcePath">Path to the source file</param>\r
152         /// <param name="title">the title number to look at</param>\r
153         private void RunScan(object sourcePath, int title)\r
154         {\r
155             try\r
156             {\r
157                 IsScanning = true;\r
158                 if (this.ScanStared != null)\r
159                     this.ScanStared(this, new EventArgs());\r
160 \r
161                 ResetLogReader();\r
162 \r
163                 string handbrakeCLIPath = Path.Combine(Application.StartupPath, "HandBrakeCLI.exe");\r
164                 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +\r
165                                 "\\HandBrake\\logs";\r
166                 string dvdInfoPath = Path.Combine(logDir, "last_scan_log.txt");\r
167 \r
168                 // Make we don't pick up a stale last_encode_log.txt (and that we have rights to the file)\r
169                 if (File.Exists(dvdInfoPath))\r
170                     File.Delete(dvdInfoPath);\r
171 \r
172                 string extraArguments = string.Empty;\r
173                 if (Properties.Settings.Default.noDvdNav)\r
174                     extraArguments = " --no-dvdnav";\r
175 \r
176                 if (title > 0)\r
177                     extraArguments += " --scan ";\r
178 \r
179                 this.hbProc = new Process\r
180                                       {\r
181                                           StartInfo =\r
182                                               {\r
183                                                   FileName = handbrakeCLIPath,\r
184                                                   Arguments =\r
185                                                       String.Format(@" -i ""{0}"" -t{1} {2} -v ", sourcePath, title, extraArguments),\r
186                                                   RedirectStandardOutput = true,\r
187                                                   RedirectStandardError = true,\r
188                                                   UseShellExecute = false,\r
189                                                   CreateNoWindow = true\r
190                                               }\r
191                                       };\r
192 \r
193                 // Start the Scan\r
194                 this.hbProc.Start();\r
195 \r
196                 this.readData = new Parser(this.hbProc.StandardError.BaseStream);\r
197                 this.readData.OnScanProgress += new ScanProgressEventHandler(this.OnScanProgress);\r
198                 this.thisDvd = DVD.Parse(this.readData);\r
199 \r
200                 // Write the Buffer out to file.\r
201                 StreamWriter scanLog = new StreamWriter(dvdInfoPath);\r
202                 scanLog.Write(this.readData.Buffer);\r
203                 scanLog.Flush();\r
204                 scanLog.Close();\r
205 \r
206                 if (this.ScanCompleted != null)\r
207                     this.ScanCompleted(this, new EventArgs());\r
208                 IsScanning = false;\r
209             }\r
210             catch (Exception exc)\r
211             {\r
212                 Console.WriteLine("frmMain.cs - scanProcess() " + exc);\r
213             }\r
214         }     \r
215 \r
216         /// <summary>\r
217         /// Read the log file\r
218         /// </summary>\r
219         private void ReadFile()\r
220         {\r
221             lock (locker)\r
222             {\r
223                 // 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
224                 // we'll need to make a copy of it.\r
225                 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";\r
226                 string logFile = Path.Combine(logDir, "last_scan_log.txt");\r
227                 string logFile2 = Path.Combine(logDir, "tmp_appReadable_log.txt");\r
228 \r
229                 try\r
230                 {\r
231                     // Make sure the application readable log file does not already exist. FileCopy fill fail if it does.\r
232                     if (File.Exists(logFile2))\r
233                         File.Delete(logFile2);\r
234 \r
235                     // Copy the log file.\r
236                     if (File.Exists(logFile))\r
237                         File.Copy(logFile, logFile2, true);\r
238                     else\r
239                     {\r
240                         ResetLogReader();\r
241                         return;\r
242                     }\r
243 \r
244                     // Start the Reader\r
245                     // Only use text which continues on from the last read line\r
246                     StreamReader sr = new StreamReader(logFile2);\r
247                     string line;\r
248                     int i = 1;\r
249                     while ((line = sr.ReadLine()) != null)\r
250                     {\r
251                         if (i > logFilePosition)\r
252                         {\r
253                             logBuffer.AppendLine(line);\r
254                             logFilePosition++;\r
255                         }\r
256                         i++;\r
257                     }\r
258                     sr.Close();\r
259                     sr.Dispose();\r
260                 }\r
261                 catch (Exception)\r
262                 {\r
263                     ResetLogReader();\r
264                 }\r
265             }\r
266         }\r
267 \r
268         /// <summary>\r
269         /// Reset the Log Reader\r
270         /// </summary>\r
271         private void ResetLogReader()\r
272         {\r
273             logFilePosition = 0;\r
274             logBuffer = new StringBuilder();\r
275         }\r
276 \r
277         /// <summary>\r
278         /// Fire an event when the scan process progresses\r
279         /// </summary>\r
280         /// <param name="sender">the sender</param>\r
281         /// <param name="currentTitle">the current title being scanned</param>\r
282         /// <param name="titleCount">the total number of titles</param>\r
283         private void OnScanProgress(object sender, int currentTitle, int titleCount)\r
284         {\r
285             this.scanProgress = string.Format("Processing Title: {0} of {1}", currentTitle, titleCount);\r
286             if (this.ScanStatusChanged != null)\r
287                 this.ScanStatusChanged(this, new EventArgs());\r
288         }\r
289     }\r
290 }