我在发布之前一直在寻找解决方案,但我放弃了!我只想使用标准输入进行交互式发送DOS命令。它运行良好,但我总是在输出dataReceived回调上获得最后一行(提示线)。
有什么想法?
Process p = null;
private void Start_Click(object sender, EventArgs e)
{
p = new Process();
p.StartInfo = new ProcessStartInfo();
p.EnableRaisingEvents = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "cmd.exe";
p.ErrorDataReceived += ErrorDataReceived;
p.OutputDataReceived += OutputDataReceived;
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
p.StandardInput.WriteLine("dir");
}
private void OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data + "n");
}
private void WriteToStandardInput_Click(object sender, EventArgs e)
{
p.StandardInput.WriteLine(txt_command.Text); //can be "dir" or "cd temp"
}
添加p.standardinput.close()解决问题,原因是当您关闭输入流时,它实际上终止了该过程(您开始使用'p.start')。因此,正如我所说,您需要为每个命令启动单独的过程。
〜Nilesh
好吧,我找到了一个解决方案...我创建了2个任务,如下所示,这些任务正在从输出和错误流中不断读取并将其打印到富文本框中。诀窍不是使用BeginRorreadline和beginOutputReadline。我希望我能够帮助别人...
public partial class Form1 : Form
{
private Process p = new Process();
private SynchronizationContext context;
public Form1()
{
InitializeComponent();
context = SynchronizationContext.Current;
}
private void Start_Click (object sender, EventArgs e)
{
p.StartInfo = new ProcessStartInfo();
p.EnableRaisingEvents = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.Start();
Task.Run(() => ReadFromStreamLoop(p.StandardOutput));
Task.Run(() => ReadFromStreamLoop(p.StandardError));
}
private void ReadFromStreamLoop (StreamReader s)
{
int count = 0;
char[] buffer = new char[1024];
do
{
StringBuilder builder = new StringBuilder();
count = s.Read(buffer, 0, 1024);
builder.Append(buffer, 0, count);
context.Post(new SendOrPostCallback(delegate (object state)
{
richTextBox1.AppendText(builder.ToString());
}), null);
} while (count > 0);
}
private void WriteToStandardInput_Click (object sender, EventArgs e)
{
p.StandardInput.WriteLine(txt_command.Text); //can be "dir" or "cd temp"
}
}
如果您正在寻找命令执行的事件结束,则每次产生新的过程。在处理结束时,您可以在主过程中显示提示。通过调用(主要)过程来管理您的环境变量。
请参阅-https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.outputdataareceivedtatareceived?view=netframework-4.7.7.2