打开命令行并在不关闭的情况下读取输出
Opening a command line and reading outputs without closing
我知道类似的问题充斥着这个网站(双关语意),但我无法在不关闭 .bat 文件的情况下让它工作,我正在 运行ning。很抱歉,我在这方面不是很熟练,但非常感谢任何帮助。
什么有效:
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = @"C:\Temp\batch.bat";
p.Start();
string output = p.StandardOutput.ReadToEnd();
string DataDate =(output.Substring(output.LastIndexOf("echo date:") + 11));
string DataID1 =(output.Substring(output.LastIndexOf("echo id1:") + 10));
string DataID2 =(output.Substring(output.LastIndexOf("echo id2:") + 10));
string DataStatus =(output.Substring(output.LastIndexOf("echo status:") + 13));
这里打开了一个batch.bat文件,它打印了几行我可以得到的字符串,例如:"echo date: 15.02.2019" goes to string DataDate。但是我想打开命令提示符并自己键入新值而不关闭命令提示符。我正在使用一个按钮 运行 上面的代码。我想我打开 cmd 进程并在每次有新行时存储它?我怎样才能使进程保持活动状态并使用更新的值更新我的字符串?例如,我可以在 cmd 提示符中输入 "echo date: 18.02.2019",然后该值将被保存。
如果我正确理解您的意图,您希望与您的过程进行交互。因此,您的流程必须支持这种交互。例如,您的批处理文件可能会提示命令,如下所示:
@echo off
:loop
echo Enter a command:
set /p userCommand=""
%userCommand%
goto :loop
您不能使用 p.StandardOutput.ReadToEnd()
,因为在输出完成之前输出流不会完成。您可以使用 OutputDataReceived
来执行异步读取。使用上面的批处理命令尝试此代码:
Process process = new Process();
process.StartInfo.FileName = @"C:\Temp\batch.bat";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
// Prepend line numbers to each line of the output.
if (!String.IsNullOrEmpty(e.Data))
{
Console.WriteLine(e.Data);// to see what happens
// parse e.Data here
}
});
process.Start();
// Asynchronously read the standard output of the spawned process.
// This raises OutputDataReceived events for each line of output.
process.BeginOutputReadLine();
process.WaitForExit();
process.Close();
更新
对于 Windows Forms 应用程序,您需要在 VS Project Properties -> Application -> Output Type
中将 Windows Application
更改为 Console Application
。或者您可以通过编辑 *.csproj
文件并将 <OutputType>WinExe</OutputType>
替换为 <OutputType>Exe</OutputType>
来完成。因此,控制台将在所有应用 运行 时间内显示,这可能是您不希望看到的。老实说,我不知道如何用其他方式做到这一点。
我知道类似的问题充斥着这个网站(双关语意),但我无法在不关闭 .bat 文件的情况下让它工作,我正在 运行ning。很抱歉,我在这方面不是很熟练,但非常感谢任何帮助。
什么有效:
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = @"C:\Temp\batch.bat";
p.Start();
string output = p.StandardOutput.ReadToEnd();
string DataDate =(output.Substring(output.LastIndexOf("echo date:") + 11));
string DataID1 =(output.Substring(output.LastIndexOf("echo id1:") + 10));
string DataID2 =(output.Substring(output.LastIndexOf("echo id2:") + 10));
string DataStatus =(output.Substring(output.LastIndexOf("echo status:") + 13));
这里打开了一个batch.bat文件,它打印了几行我可以得到的字符串,例如:"echo date: 15.02.2019" goes to string DataDate。但是我想打开命令提示符并自己键入新值而不关闭命令提示符。我正在使用一个按钮 运行 上面的代码。我想我打开 cmd 进程并在每次有新行时存储它?我怎样才能使进程保持活动状态并使用更新的值更新我的字符串?例如,我可以在 cmd 提示符中输入 "echo date: 18.02.2019",然后该值将被保存。
如果我正确理解您的意图,您希望与您的过程进行交互。因此,您的流程必须支持这种交互。例如,您的批处理文件可能会提示命令,如下所示:
@echo off
:loop
echo Enter a command:
set /p userCommand=""
%userCommand%
goto :loop
您不能使用 p.StandardOutput.ReadToEnd()
,因为在输出完成之前输出流不会完成。您可以使用 OutputDataReceived
来执行异步读取。使用上面的批处理命令尝试此代码:
Process process = new Process();
process.StartInfo.FileName = @"C:\Temp\batch.bat";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
// Prepend line numbers to each line of the output.
if (!String.IsNullOrEmpty(e.Data))
{
Console.WriteLine(e.Data);// to see what happens
// parse e.Data here
}
});
process.Start();
// Asynchronously read the standard output of the spawned process.
// This raises OutputDataReceived events for each line of output.
process.BeginOutputReadLine();
process.WaitForExit();
process.Close();
更新
对于 Windows Forms 应用程序,您需要在 VS Project Properties -> Application -> Output Type
中将 Windows Application
更改为 Console Application
。或者您可以通过编辑 *.csproj
文件并将 <OutputType>WinExe</OutputType>
替换为 <OutputType>Exe</OutputType>
来完成。因此,控制台将在所有应用 运行 时间内显示,这可能是您不希望看到的。老实说,我不知道如何用其他方式做到这一点。