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