A pesar del hecho de que el uso de GenerateConsoleCtrlEvent para el envío de la señal Ctrl + C es una respuesta correcta que necesita una aclaración significativa para conseguir que funcione en diferentes. Tipos de aplicaciones NET.
Si su aplicación .NET no utiliza su propia consola (WinForms/WPF/servicio de Windows/ASP.NET) de flujo básico es:
- proceso de conexión a la consola .NET principal del proceso que desea Ctrl + C
- Prevenir proceso principal .NET se detenga debido evento Ctrl + C con SetConsoleCtrlHandler
- Generar evento consola para actual consola con GenerateConsoleCtrlEvent (processGroupId debe ser cero! Responder con código que envía p.SessionId no lo hará trabajo e incorrecto)
- Desconectar de la consola y restaurar Ctrl + C manipulación por el proceso principal
El siguiente fragmento de código muestra cómo hacerlo:
Process p;
if (AttachConsole((uint)p.Id)) {
SetConsoleCtrlHandler(null, true);
try {
if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT,0))
return false;
p.WaitForExit();
} finally {
FreeConsole();
SetConsoleCtrlHandler(null, false);
}
return true;
}
donde SetConsoleCtrlHandler, FreeConsole, AttachConsole y GenerateConsoleCtrlEvent son métodos WinAPI nativas:
internal const int CTRL_C_EVENT = 0;
[DllImport("kernel32.dll")]
internal static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
internal static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
// Delegate type to be used as the Handler Routine for SCCH
delegate Boolean ConsoleCtrlDelegate(uint CtrlType);
Las cosas se vuelven más complejas si necesita enviar Ctrl + C desde la aplicación de consola .NET. El enfoque no funcionará porque AttachConsole devuelve falso en este caso (la aplicación de la consola principal ya tiene una consola). Es posible llamar a FreeConsole antes de la llamada a AttachConsole, pero como resultado se perderá la consola de la aplicación .NET original, lo cual no es aceptable en la mayoría de los casos.
Mi solución para este caso (que realmente funciona y no tiene efectos secundarios para la consola principal proceso .NET):
- crear pequeñas programa de consola .NET de apoyo que acepta el ID del proceso de argumentos de línea de comandos, pierde su propia consola con FreeConsole antes de la llamada y envía AttachConsole Ctrl + C para procesos con código mencionado anteriormente
- proceso de consola .NET principal objetivo simplemente invoca esta utilidad en el nuevo proceso cuando se van a enviar Ctrl + C para otro proceso de consola
Tenga en cuenta que solo funciona si el proceso está tratando de leer desde la entrada estándar. Cerrar el stdin no hace nada hasta que el programa intente leer algo de él. – Doug
por qué muestra esta excepción "No se ha redireccionado a StandardIn". ? estoy usando ffmpeg para la captura de pantalla – Ahmad