C# Process Dispose 抛出标准错误未重定向

发布于 2024-12-18 20:20:50 字数 3016 浏览 0 评论 0原文

我正在创建一个 Process 对象,以使用具有正确属性集的 ProcessStartInfo 来运行进程。在我考虑处理我的 Process 对象之前,这种方法一直有效。最初,我将其包装在 using 块中,但失败了,之后我在退出事件处理程序中显式调用 Close 和 Dispose。

代码如下所示:

var processInfo = new ProcessStartInfo("program.exe", argument)
{
    RedirectStandardError = true,
    CreateNoWindow = true,
    UseShellExecute = false
};
var proc = new Process { StartInfo = processInfo, EnableRaisingEvents = true };
proc.Exited += EventHandler;
proc.Start();
proc.WaitForExit();

private static void EventHandler(object sender, EventArgs e)
{
    var p = sender as Process;
    if (p == null)
        return;
    var stdErr = p.StandardError.ReadToEnd();
    if (!string.IsNullOrEmpty(stdErr))
        Console.WriteLine(string.Format("Log:({0}) {1} ", p.ExitCode, stdErr));
    p.Close();
    p.Dispose();
}

当我添加 p.Close() 和 p.Dispose() 时,出现以下错误:

System.InvalidOperationException : StandardError has not been redirected.
   at System.Diagnostics.Process.get_StandardError()

StackTrace 如下:

Unhandled exception in remote appdomain: System.InvalidOperationException: StandardError has not been redirected.
   at System.Diagnostics.Process.get_StandardError()
   at namespace.EventHandler(Object sender, EventArgs e) in c:\BuildAgent\work\70df16b46ad15c54\Source\Blah.cs:line 318
   at System.Diagnostics.Process.OnExited()
   at System.Diagnostics.Process.RaiseOnExited()
   at System.Diagnostics.Process.CompletionCallback(Object context, Boolean wasSignaled)
   at System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context(Object state, Boolean timedOut)
   at System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context_f(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)

即使以下代码也会引发相同的异常:

var processInfo = new ProcessStartInfo("program.exe", argument)
{
    RedirectStandardError = true,
    CreateNoWindow = true,
    UseShellExecute = false
};
using(var proc = new Process { StartInfo = processInfo, EnableRaisingEvents =true })
{
    proc.Exited += EventHandler;
    proc.Start();
    proc.WaitForExit();
}

private static void EventHandler(object sender, EventArgs e)
{
    var p = sender as Process;
    if (p == null)
        return;
    var stdErr = p.StandardError.ReadToEnd();
    if (!string.IsNullOrEmpty(stdErr))
        Console.WriteLine(string.Format("Log:({0}) {1} ", p.ExitCode, stdErr));

}

I am crating a Process object to run a process with a ProcessStartInfo with the correct properties set. This was working until I thought about disposing my Process object. Initially I wrapped it around a using block and that failed after which I explicitly call Close and Dispose in the Exited Event Handler.

The code looks like follows:

var processInfo = new ProcessStartInfo("program.exe", argument)
{
    RedirectStandardError = true,
    CreateNoWindow = true,
    UseShellExecute = false
};
var proc = new Process { StartInfo = processInfo, EnableRaisingEvents = true };
proc.Exited += EventHandler;
proc.Start();
proc.WaitForExit();

private static void EventHandler(object sender, EventArgs e)
{
    var p = sender as Process;
    if (p == null)
        return;
    var stdErr = p.StandardError.ReadToEnd();
    if (!string.IsNullOrEmpty(stdErr))
        Console.WriteLine(string.Format("Log:({0}) {1} ", p.ExitCode, stdErr));
    p.Close();
    p.Dispose();
}

When I add the p.Close() and p.Dispose() I get the following error:

System.InvalidOperationException : StandardError has not been redirected.
   at System.Diagnostics.Process.get_StandardError()

StackTrace as follows:

Unhandled exception in remote appdomain: System.InvalidOperationException: StandardError has not been redirected.
   at System.Diagnostics.Process.get_StandardError()
   at namespace.EventHandler(Object sender, EventArgs e) in c:\BuildAgent\work\70df16b46ad15c54\Source\Blah.cs:line 318
   at System.Diagnostics.Process.OnExited()
   at System.Diagnostics.Process.RaiseOnExited()
   at System.Diagnostics.Process.CompletionCallback(Object context, Boolean wasSignaled)
   at System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context(Object state, Boolean timedOut)
   at System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context_f(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)

Even the following code throws the same exception:

var processInfo = new ProcessStartInfo("program.exe", argument)
{
    RedirectStandardError = true,
    CreateNoWindow = true,
    UseShellExecute = false
};
using(var proc = new Process { StartInfo = processInfo, EnableRaisingEvents =true })
{
    proc.Exited += EventHandler;
    proc.Start();
    proc.WaitForExit();
}

private static void EventHandler(object sender, EventArgs e)
{
    var p = sender as Process;
    if (p == null)
        return;
    var stdErr = p.StandardError.ReadToEnd();
    if (!string.IsNullOrEmpty(stdErr))
        Console.WriteLine(string.Format("Log:({0}) {1} ", p.ExitCode, stdErr));

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文