卡住C#中的控制台应用程序中的GenerateConsoleCtrlEvent
我最困难的时间试图让这个工作,希望你们之前做过这个。卡住C#中的控制台应用程序中的GenerateConsoleCtrlEvent
我有一个C#控制台应用程序正在运行继承其控制台的子进程。我想要一个由外部应用程序捕获的ctrl-c传递给内部应用程序,以便它可以很好地关闭。
我有一些非常简单的代码。我开始一个Process,然后用WaitForExit(10)轮询它。我还有一个注册的CancelKeyPress处理程序,它在触发时将bool设置为true。轮询循环也会检查它,如果它是真的,它会调用GenerateConsoleCtrlEvent()(我已通过pinvoke映射)。
我已经尝试了很多组合的参数GenerateConsoleCtrlEvent()。 0或1表示第一个参数,0或第二个参数的子进程ID。似乎没有任何工作。有时我得到一个错误的回来,Marshal.GetLastWin32Error()返回0,有时我会回到真实。但是没有一个导致子应用程序接收到ctrl-c。要绝对确定,我写了一个测试C#应用程序作为子应用程序,它打印出它正在发生的事情,并验证当它运行时手动输入ctrl-c确实会导致它退出。
我几个小时一直对我的头撞。任何人都可以给我一些指向哪里去与此?
不太确定这是一个好方法。这只适用于如果使用CREATE_NEW_PROCESS_GROUP标志为CreateProcess()
创建子进程。但System.Diagnostics.Process类不支持这一点。
考虑使用Main()方法的返回值。在Windows SDK中已经为Ctrl + C中止定义了一个唯一值STATUS_CONTROL_C_EXIT或0xC000013A。父进程可以从Process.ExitCode
属性获取返回代码。
你有没有这方面的运气?我的理解是,当您在控制台中按CTRL + C时,默认情况下所有连接到控制台的进程都会接收它,而不仅仅是父级进程。这里有一个例子:
Child.cs:
using System;
public class MyClass
{
public static void CtrlCHandler(object sender, ConsoleCancelEventArgs args)
{
Console.WriteLine("Child killed by CTRL+C.");
}
public static void Main()
{
Console.WriteLine("Child start.");
Console.CancelKeyPress += CtrlCHandler;
System.Threading.Thread.Sleep(4000);
Console.WriteLine("Child finish.");
}
}
Parent.cs:
using System;
public class MyClass
{
public static void CtrlCHandler(object sender, ConsoleCancelEventArgs args)
{
Console.WriteLine("Parent killed by CTRL+C.");
}
public static void Main()
{
Console.CancelKeyPress += CtrlCHandler;
Console.WriteLine("Parent start.");
System.Diagnostics.Process child = new System.Diagnostics.Process();
child.StartInfo.UseShellExecute = false;
child.StartInfo.FileName = "child.exe";
child.Start();
child.WaitForExit();
Console.WriteLine("Parent finish.");
}
}
输出:
Y:\>parent
Parent start.
Child start.
Parent killed by CTRL+C.
Child killed by CTRL+C.
^C
Y:\>parent
Parent start.
Child start.
Child finish.
Parent finish.
所以我不会想到你需要做任何特别的事情。但是,如果您确实需要自己生成CTRL + C事件,事情可能并不那么容易。我不确定你描述的问题,但据我所知,只能发送CTRL + C事件到所有连接到控制台窗口的进程。如果你分离一个进程,你不能发送CTRL + C事件。如果你想选择哪些进程发送CTRL + C事件,你似乎需要为每一个创建新的控制台窗口。我不知道是否有办法在没有可见窗口的情况下执行此操作,或者您想要使用管道重定向I/O。
我遇到同样的问题。 GenerateConsoleCtrlEvent似乎被破坏。它不影响进程,不管它是否具有控制台窗口,也不影响它是否以CREATE_NEW_PROCESS_GROUP开头。我试过了所有的东西,似乎没有办法彻底关闭一个以Process启动的控制台应用程序。如果它不是调用进程的控制台窗口的一部分,则启动或CreateProcess。 – Triynko 2013-04-22 19:12:49