我正在创建CaptureConsole类,如下所示:
public class CaptureConsole
{
private string ExecutableName;
private string[] Parameters;
private DataReceivedEventHandler OnCaptureOutput;
private DataReceivedEventHandler OnCaptureError;
public CaptureConsole(string _executableName, string[] _parameters, DataReceivedEventHandler _onCaptureOutput, DataReceivedEventHandler _onCaptureError)
{
this.ExecutableName = _executableName;
this.Parameters = _parameters;
this.OnCaptureOutput = _onCaptureOutput;
this.OnCaptureError = _onCaptureError;
}
public void Run()
{
ProcessStartInfo startInfo = new ProcessStartInfo()
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = this.ExecutableName
};
// Parsing arguments
for (int i = 0; i < this.Parameters.Length; i++)
{
if (i == 0)
startInfo.Arguments = this.Parameters[0];
if (i > 0)
{
startInfo.Arguments += " ";
startInfo.Arguments += this.Parameters[i];
}
}
Process process = new Process()
{
StartInfo = startInfo
};
process.OutputDataReceived += this.OnCaptureOutput;
process.ErrorDataReceived += this.OnCaptureError;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.CreateNoWindow = true;
process.EnableRaisingEvents = true;
Thread processThread = new Thread(() =>
{
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
//process.WaitForExit();
}) { IsBackground = true };
processThread.Start();
}
}
并像这样使用它:
private void button1_Click(object sender, EventArgs e)
{
const string exeName = "ping.exe";
string[] parameters = new string[] { "127.0.0.1", "-t" };
CaptureConsole RunConsole = new CaptureConsole(exeName, parameters, ShowOutput, ShowError);
RunConsole.Run();
}
void ShowOutput(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
this.InvokeEx(x => x.listBox1.Items.Add(e.Data));
}
private void ShowError(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
this.InvokeEx(x => x.listBox1.Items.Add(e.Data));
}
这会按照需要运行,但我注意到如果我关闭应用程序,conhost.exe和ping.exe仍在任务管理器中运行,因为我使用-t参数进行ping操作。如何在应用程序关闭时确保我运行的可执行文件(在我的情况下为ping.exe)即使尚未完成其工作也会关闭?
答案 0 :(得分:1)
我想用更好的方法解决这个问题,使用类析构函数本身。我测试了同时运行超过10个ping进程,关闭应用程序杀死了所有这些进程: - )
使用线程来运行进程允许应用程序在运行进程时响应..
// Example of ShowOutput and ShowError that will be used in Form1.cs
//void ShowOutput(object sender, DataReceivedEventArgs e)
//{
// if (e.Data != null)
// this.InvokeEx(x => x.listBox1.Items.Add(e.Data));
//}
//private void ShowError(object sender, DataReceivedEventArgs e)
//{
// if (e.Data != null)
// this.InvokeEx(x => x.listBox1.Items.Add(e.Data));
//}
namespace WindowsFormsApplication1
{
public class CaptureConsole : IDisposable
{
private string ExecutableName;
private string[] Parameters;
private Process ConsoleProcess = new Process();
private bool disposed = false; // from MSDN
private DataReceivedEventHandler OnCaptureOutput;
private DataReceivedEventHandler OnCaptureError;
public CaptureConsole() { }
public CaptureConsole(string _executableName, string[] _parameters, DataReceivedEventHandler _onCaptureOutput, DataReceivedEventHandler _onCaptureError)
{
this.ExecutableName = _executableName;
this.Parameters = _parameters;
this.OnCaptureOutput = _onCaptureOutput;
this.OnCaptureError = _onCaptureError;
ProcessStartInfo startInfo = new ProcessStartInfo()
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = this.ExecutableName
};
// Parsing arguments
for (int i = 0; i < this.Parameters.Length; i++)
{
if (i == 0)
startInfo.Arguments = this.Parameters[0];
if (i > 0)
{
startInfo.Arguments += " ";
startInfo.Arguments += this.Parameters[i];
}
}
Process process = new Process()
{
StartInfo = startInfo
};
process.OutputDataReceived += this.OnCaptureOutput;
process.ErrorDataReceived += this.OnCaptureError;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.CreateNoWindow = true;
process.EnableRaisingEvents = true;
ConsoleProcess = process;
}
public Process Run(int StartDelay = 250)
{
Thread processThread = new Thread(() =>
{
ConsoleProcess.Start();
ConsoleProcess.BeginOutputReadLine();
ConsoleProcess.BeginErrorReadLine();
}) { IsBackground = true };
processThread.Start();
Thread.Sleep(StartDelay);
return ConsoleProcess;
}
//Implement IDisposable.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// from MSDN
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Manual release of managed resources.
}
// Release unmanaged resources.
try
{
ConsoleProcess.Kill();
}
catch { }
finally
{
disposed = true;
}
}
}
~CaptureConsole() { Dispose(false); }
}
}
示例使用Form1的代码:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
const string exeName = "ping.exe";
string[] parameters = new string[] { "127.0.0.1", "-t" };
Process externalProcess = new Process();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
CaptureConsole RunConsole = new CaptureConsole(exeName, parameters, ShowStdOutput, ShowStdError);
externalProcess = RunConsole.Run(450);
this.InvokeEx(x => x.listBox1.Items.Add(String.Format("Process Started: {0}", externalProcess.StartTime)));
}
void ShowStdOutput(object sender, DataReceivedEventArgs e)
{
try
{
if (e.Data != null && !externalProcess.HasExited)
this.InvokeEx(x => x.listBox1.Items.Add(e.Data));
}
catch { };
}
private void ShowStdError(object sender, DataReceivedEventArgs e)
{
try
{
if (e.Data != null && !externalProcess.HasExited)
this.InvokeEx(x => x.listBox1.Items.Add(e.Data));
}
catch { };
}
}
}