I have a simple app that runs another external existing console app via Process and intercepts its output. To do so, I use this monstrosity:
private Process process = new Process(); private string myPath = ""; private List<string> stdout = new List<string>(); private ConsoleWindow console = new ConsoleWindow(); //Launcher in MainWindow private void ProcessButton_Click(object sender, RoutedEventArgs e) { process.Refresh(); process.EnableRaisingEvents = true; process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived); process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived); process.Exited += new System.EventHandler(process_Exited); process.StartInfo.FileName = progPath; process.StartInfo.Arguments = generateArgs(); process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; try { process.Start(); MainWindow.IsEnabled = false; } catch (Exception args) { throw; } this.Dispatcher.Invoke(() => { if (console.Visibility == Visibility.Visible) { console.clearLogBox(); console.Activate(); } else { console.Show(); console.clearLogBox(); } }); process.BeginErrorReadLine(); process.BeginOutputReadLine(); } //Events void process_Exited(object sender, EventArgs e) { File.WriteAllLines(@"N:\std.txt", stdout.ToArray()); stdout.Clear(); if (process.ExitCode == 0) MessageBox.Show("thing!"); else MessageBox.Show("thing2"); this.Dispatcher.Invoke(() => { MainWindow.IsEnabled = true; }); process.CancelErrorRead(); process.CancelOutputRead(); process.EnableRaisingEvents = false; process.OutputDataReceived -= new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived); process.ErrorDataReceived -= new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived); process.Exited -= new System.EventHandler(process_Exited); } void process_ErrorDataReceived(object sender, DataReceivedEventArgs e) { this.Dispatcher.Invoke(() => { console.addLogLine(e.Data + "\n"); }); stdout.Add(e.Data + "\n"); }
MSVS code analyzer keeps telling me that I should implement IDisposale for my MainWindow
class because it uses process. I did some googling and could not find any conclusive answer if it is was really necessary. One of MSDN docs says that old information, associated with previous process instance is automatically discarded/disposed upon new Start(). Some answers on SO also said there isnt anything particularly bad reusing the same process instance.
However, this question really bugs me and I’m curious if anyone with experience can weight in a few words how would he implement something like this properly? Shall I just manually dispose process after its done and implement a simple logic to keep track of this state in the code? Or try to do it via IDisposable? Not sure why “Main Window” in WPF even need it since it is the main instance of app that requires no disposal.