1 /* frmActivityWindow.cs $
\r
3 This file is part of the HandBrake source code.
\r
4 Homepage: <http://handbrake.fr>.
\r
5 It may be used under the terms of the GNU General Public License. */
\r
8 using System.Windows.Forms;
\r
10 using System.Threading;
\r
11 using System.Runtime.InteropServices;
\r
12 using Handbrake.EncodeQueue;
\r
13 using Microsoft.Win32;
\r
18 public partial class frmActivityWindow : Form
\r
20 delegate void SetTextCallback(string text);
\r
23 QueueHandler encodeQueue;
\r
24 int position; // Position in the arraylist reached by the current log output in the rtf box.
\r
25 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
\r
26 private frmMain mainWin;
\r
29 /// This window should be used to display the RAW output of the handbrake CLI which is produced during an encode.
\r
31 public frmActivityWindow(string file, QueueHandler eh, frmMain mw)
\r
33 InitializeComponent();
\r
35 rtf_actLog.Text = string.Empty;
\r
41 // When the window closes, we want to abort the monitor thread.
\r
42 this.Disposed += new EventHandler(forceQuit);
\r
44 // Print the Log header in the Rich text box.
\r
47 if (file == "last_scan_log.txt")
\r
48 txt_log.Text = "Scan Log";
\r
49 else if (file == "last_encode_log.txt")
\r
50 txt_log.Text = "Encode Log";
\r
52 // Start a new thread which will montior and keep the log window up to date if required/
\r
53 startLogThread(read_file);
\r
57 /// Displays the Log header
\r
59 private void displayLogHeader()
\r
61 // Add a header to the log file indicating that it's from the Windows GUI and display the windows version
\r
62 rtf_actLog.AppendText(String.Format("### Windows GUI {1} {0} \n", Properties.Settings.Default.hb_build, Properties.Settings.Default.hb_version));
\r
63 rtf_actLog.AppendText(String.Format("### Running: {0} \n###\n", Environment.OSVersion));
\r
64 rtf_actLog.AppendText(String.Format("### CPU: {0} \n", getCpuCount()));
\r
65 rtf_actLog.AppendText(String.Format("### Ram: {0} MB \n", TotalPhysicalMemory()));
\r
66 rtf_actLog.AppendText(String.Format("### Screen: {0}x{1} \n", screenBounds().Bounds.Width, screenBounds().Bounds.Height));
\r
67 rtf_actLog.AppendText(String.Format("### Temp Dir: {0} \n", Path.GetTempPath()));
\r
68 rtf_actLog.AppendText(String.Format("### Install Dir: {0} \n", Application.StartupPath));
\r
69 rtf_actLog.AppendText(String.Format("### Data Dir: {0} \n", Application.UserAppDataPath));
\r
70 rtf_actLog.AppendText("#########################################\n\n");
\r
71 if (encodeQueue.isEncoding && encodeQueue.lastQueueItem.Query != String.Empty)
\r
73 rtf_actLog.AppendText("### CLI Query: " + encodeQueue.lastQueueItem.Query + "\n\n");
\r
74 rtf_actLog.AppendText("#########################################\n\n");
\r
79 /// Starts a new thread which runs the autoUpdate function.
\r
81 /// <param name="file"> File which will be used to populate the Rich text box.</param>
\r
82 private void startLogThread(string file)
\r
86 string logFile = Path.Combine(logDir, file);
\r
87 if (File.Exists(logFile))
\r
89 // Start a new thread to run the autoUpdate process
\r
90 monitor = new Thread(autoUpdate);
\r
91 monitor.IsBackground = true;
\r
95 rtf_actLog.AppendText("\n\n\nERROR: The log file could not be found. \nMaybe you cleared your system's tempory folder or maybe you just havn't run an encode yet. \nTried to find the log file in: " + logFile);
\r
98 catch (Exception exc)
\r
100 MessageBox.Show("startLogThread(): Exception: \n" + exc);
\r
105 /// Updates the log window with any new data which is in the log file.
\r
106 /// This is done every 5 seconds.
\r
108 /// <param name="state"></param>
\r
109 private void autoUpdate(object state)
\r
113 Boolean lastUpdate = false;
\r
114 updateTextFromThread();
\r
117 if (encodeQueue.isEncoding || mainWin.isScanning)
\r
118 updateTextFromThread();
\r
121 // The encode may just have stoped, so, refresh the log one more time before restarting it.
\r
122 if (lastUpdate == false)
\r
123 updateTextFromThread();
\r
125 lastUpdate = true; // Prevents the log window from being updated when there is no encode going.
\r
126 position = 0; // There is no encoding, so reset the log position counter to 0 so it can be reused
\r
128 Thread.Sleep(5000);
\r
131 catch (ThreadAbortException)
\r
133 // Do Nothing. This is needed since we run thread.abort().
\r
134 // Should probably find a better way of making this work at some point.
\r
136 catch (Exception exc)
\r
138 MessageBox.Show("autoUpdate(): Exception: \n" + exc);
\r
143 /// Finds any new text in the log file and calls a funciton to display this new text.
\r
145 private void updateTextFromThread()
\r
149 String info = readFile();
\r
150 if (info.Contains("has exited"))
\r
151 info += "\n ############ End of Log ############## \n";
\r
155 catch (Exception exc)
\r
157 MessageBox.Show("updateTextFromThread(): Exception: \n" + exc);
\r
162 /// Updates the rich text box with anything in the string text.
\r
164 /// <param name="text"></param>
\r
165 private void SetText(string text)
\r
169 // InvokeRequired required compares the thread ID of the
\r
170 // calling thread to the thread ID of the creating thread.
\r
171 // If these threads are different, it returns true.
\r
172 if (IsHandleCreated) // Make sure the windows has a handle before doing anything
\r
174 if (rtf_actLog.InvokeRequired)
\r
176 SetTextCallback d = new SetTextCallback(SetText);
\r
177 Invoke(d, new object[] { text });
\r
180 rtf_actLog.AppendText(text);
\r
183 catch (Exception exc)
\r
185 MessageBox.Show("SetText(): Exception: \n" + exc);
\r
190 /// Read the log file, and store the data in a List.
\r
192 /// <returns></returns>
\r
193 private String readFile()
\r
195 String appendText = String.Empty;
\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 logFile = Path.Combine(logDir, read_file);
\r
201 string logFile2 = Path.Combine(logDir, "tmp_appReadable_log.txt");
\r
203 // Make sure the application readable log file does not already exist. FileCopy fill fail if it does.
\r
204 if (File.Exists(logFile2))
\r
205 File.Delete(logFile2);
\r
207 // Copy the log file.
\r
208 File.Copy(logFile, logFile2);
\r
210 // Open the copied log file for reading
\r
211 StreamReader sr = new StreamReader(logFile2);
\r
214 while ((line = sr.ReadLine()) != null)
\r
218 appendText += line + Environment.NewLine;
\r
228 catch (Exception exc)
\r
230 MessageBox.Show("Error in readFile() \n Unable to read the log file.\n You may have to restart HandBrake.\n Error Information: \n\n" + exc, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
\r
236 /// Kills the montior thead when the window is disposed of.
\r
238 /// <param name="sender"></param>
\r
239 /// <param name="e"></param>
\r
240 private void forceQuit(object sender, EventArgs e)
\r
242 if (monitor != null)
\r
244 while (monitor.IsAlive)
\r
251 #region User Interface
\r
253 private void mnu_copy_log_Click(object sender, EventArgs e)
\r
255 if (rtf_actLog.SelectedText != "")
\r
256 Clipboard.SetDataObject(rtf_actLog.SelectedText, true);
\r
258 Clipboard.SetDataObject(rtf_actLog.Text, true);
\r
260 private void mnu_openLogFolder_Click(object sender, EventArgs e)
\r
262 string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
\r
263 string windir = Environment.GetEnvironmentVariable("WINDIR");
\r
264 System.Diagnostics.Process prc = new System.Diagnostics.Process();
\r
265 prc.StartInfo.FileName = windir + @"\explorer.exe";
\r
266 prc.StartInfo.Arguments = logDir;
\r
269 private void btn_copy_Click(object sender, EventArgs e)
\r
271 if (rtf_actLog.SelectedText != "")
\r
272 Clipboard.SetDataObject(rtf_actLog.SelectedText, true);
\r
274 Clipboard.SetDataObject(rtf_actLog.Text, true);
\r
276 private void btn_scan_log_Click(object sender, EventArgs e)
\r
278 // Switch to the scan log.
\r
280 if (monitor != null)
\r
283 rtf_actLog.Clear();
\r
284 read_file = "last_scan_log.txt";
\r
285 displayLogHeader();
\r
286 startLogThread(read_file);
\r
287 txt_log.Text = "Scan Log";
\r
289 private void btn_encode_log_Click(object sender, EventArgs e)
\r
291 // Switch to the encode log
\r
293 if (monitor != null)
\r
296 rtf_actLog.Clear();
\r
297 read_file = "last_encode_log.txt";
\r
299 displayLogHeader();
\r
300 startLogThread(read_file);
\r
301 txt_log.Text = "Encode Log";
\r
306 #region System Information
\r
307 private struct MEMORYSTATUS // Unused var's are requred here.
\r
309 public UInt32 dwLength;
\r
310 public UInt32 dwMemoryLoad;
\r
311 public UInt32 dwTotalPhys; // Used
\r
312 public UInt32 dwAvailPhys;
\r
313 public UInt32 dwTotalPageFile;
\r
314 public UInt32 dwAvailPageFile;
\r
315 public UInt32 dwTotalVirtual;
\r
316 public UInt32 dwAvailVirtual;
\r
319 [DllImport("kernel32.dll")]
\r
320 private static extern void GlobalMemoryStatus
\r
322 ref MEMORYSTATUS lpBuffer
\r
326 /// Returns the total physical ram in a system
\r
328 /// <returns></returns>
\r
329 public uint TotalPhysicalMemory()
\r
331 MEMORYSTATUS memStatus = new MEMORYSTATUS();
\r
332 GlobalMemoryStatus(ref memStatus);
\r
334 uint MemoryInfo = memStatus.dwTotalPhys;
\r
335 MemoryInfo = MemoryInfo / 1024 / 1024;
\r
341 /// Get the number of CPU Cores
\r
343 /// <returns>Object</returns>
\r
344 public Object getCpuCount()
\r
346 RegistryKey RegKey = Registry.LocalMachine;
\r
347 RegKey = RegKey.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
\r
348 return RegKey.GetValue("ProcessorNameString");
\r
352 /// Get the System screen size information.
\r
354 /// <returns>System.Windows.Forms.Scree</returns>
\r
355 public Screen screenBounds()
\r
357 return Screen.PrimaryScreen;
\r