gpt4 book ai didi

c# - 使用 Process.kill 异常终止进程后读取 StdOut

转载 作者:太空宇宙 更新时间:2023-11-03 16:05:17 25 4
gpt4 key购买 nike

我正在通过 c# Diagnostics.Process 类调用一个 exe,并从它的 StdOut 读取输出。如果进程没有在指定时间内自动终止,则会强制终止该进程,例如:

process.StartInfo.FileName = @"D:\t.exe";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = false;

process.WaitForExit(500);

if (!process.HasExited)
{
process.Kill();
process.WaitForExit();
}
string stdOutContents = process.StandardOutput.ReadToEnd();

现在的问题是,当 exe 正常终止时,代码可以成功运行。但如果它无法正常终止(通常 exe 会在某处陷入无限循环),stdOutContents 将被读取为空字符串。

我如何在进程终止后读取 StdOut(不使用 process.OutputDataReceived 事件技术)? (已经证实,有问题的 exe 确实总是在 StdOut 上写入一些东西,即使它卡在某个地方也是如此)。


更新 1

有关正在调用的 Exe 的详细信息(在这个问题中称为“ native 应用程序”)

这是一个用c语言实现并使用MS C++编译器编译的小工具。它在完成工作的同时将状态信息输出到 StdOut(使用 putchar)。

只有两种可能的操作情况:

  1. 它将成功运行,同时将一些数据打印到 StdOut。
  2. 它会正常运行到某个点(同时在StdOut上输出数据)然后陷入死循环。 (这是可接受的行为)。

这两种情况都已使用 cmd 进行了验证。

关于新尝试的详细信息

我写了一个 c# 应用程序(称为虚拟应用程序),它模仿了 native 应用程序的行为,并且这段代码工作正常。但是,当运行 native 应用程序时,我什么也得不到。

我不明白为什么代码无法读取原生应用输出的内容?

我还尝试使用 OutputDataReceived 的事件处理程序。当代码试图终止进程时,它仅使用 args.Data = null 调用一次。检查虚拟应用程序的行为表明,当调用 process.kill 时,会使用 args.Data = null 调用处理程序。所以这似乎是这两个应用程序的标准行为。

我还尝试更改 native 应用程序的换行符。由于是c语言实现的,所以用\n换行。我尝试使用两个\r\n 对作为换行符,但 StdOut 仍然是空白(对于情况 2)。

最佳答案

我有同样的审讯和 doc of Process.Kill

Data edited by the process or resources allocated to the process can be lost if you call Kill.

这似乎表明您不能依赖于读取进程的 StandardOutput,尽管没有明确说明输出/错误流已被处理。

我终于从这个答案中得到启发 How to spawn a process and capture its STDOUT in .NET?

我使用以下代码:

var info = new ProcessStartInfo("some.exe");
info.CreateNoWindow = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;

using (var p = new Process())
{
p.StartInfo = info;
var output = new StringBuilder();
p.OutputDataReceived += (sender, eventArgs) =>
{
output.AppendLine(eventArgs.Data);
};
p.Start();
p.BeginOutputReadLine();
if (!p.WaitForExit(5000))
{
Console.WriteLine("Taking too long...");
p.Kill();
Console.WriteLine("Process killed, output :\n" + output);
}
}

相同的模式可以用于 ErrorDataReceived

请注意,子进程可能会遗漏一些未刷新的输出,但在我的情况下,我对需要终止的进程的期望不高,至多是一些用于调试目的的信息。

关于c# - 使用 Process.kill 异常终止进程后读取 StdOut,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19742022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com