0

我有一个控制台应用程序。我希望它开始一个过程并在该过程结束时结束。如果用户点击 ctrl + c,我不希望应用程序关闭。如果我设置 UseShellExecute = false,那么这正是我所期望的 - Ctrl C 被忽略。

但似乎在UseShellExecute:true时,ctrl+c事件传播到子进程,即使父进程取消也关闭子进程。

我不能 UseShellExecute:true 因为我想捕获控制台输出和控制台错误事件。

当 UseShellExecute:false 时,如何阻止 ctrl+c 事件到达子进程?

public static int Main(string[] args)
{
    Console.CancelKeyPress += ConsoleOnCancelKeyPress;

        Process process = new Process()
        {
            StartInfo = new ProcessStartInfo()
            {
                FileName = filename,
                Arguments = args,
                UseShellExecute = false,
                RedirectStandardError = true,
                RedirectStandardOutput = true,
                RedirectStandardInput = true,
                CreateNoWindow = false,
            }
        };

        process.OutputDataReceived += process_OutputDataReceived;
        process.ErrorDataReceived += process_ErrorDataReceived;

        process.Start();

        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        process.WaitForExit();

        return -1;
}

private static void ConsoleOnCancelKeyPress(object sender, ConsoleCancelEventArgs consoleCancelEventArgs)
{
    consoleCancelEventArgs.Cancel = true;
}
4

2 回答 2

1

我用一组级联的进程解决了这个问题。进程“A”使用 UseShellExecute=true 启动进程“B”。进程“B”使用 UseShellExecute=false 启动进程“C”。

当进程“A”收到 Ctrl+C 时,它会在我想要的时间段内捕获它。然后它通过 process.CloseMainWindow() 将它传递给“B”。

由于 UseShellExecute=false,进程“B”仍然可以读取进程“C”(我正在尝试托管和监控)的控制台输出。从“A”发送的 CloseMainWindow 直接发送到“B”和“C”并关闭这两个进程。

我很幸运,我的逻辑可以在进程之间如此清晰地分割。否则,我认为 Stephen Toub 的这篇博客文章是 Dave 建议的键盘陷阱的一个很好的起点。尽管我没有排除用户错误,但我无法让它在我的 x64 进程中工作。http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx

于 2013-07-25T07:13:11.837 回答
0

使用键盘挂钩在控制台中捕获 Ctrl-C 这将覆盖该操作。使用此代码启用该功能:

http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx

于 2013-07-16T01:43:51.813 回答