java - tipos - ¿Enviando una señal arbitraria en Windows?
para que sirve un generador de funciones (6)
Me pregunto si las PsTools de, ahora propiedad de Microsoft, SysInternals te ayudarían.
Linux admite el envío de una señal Posix arbitraria, como SIGINT
o SIGTERM
a un proceso que utiliza kill
Command. Si bien SIGINT
y SIGTERM
son simplemente viejas formas aburridas de finalizar un proceso de una manera amistosa o no tan amigable, SIGQUIT
está destinado a activar un volcado de SIGQUIT
. Esto se puede utilizar para activar una máquina virtual Java en ejecución para imprimir un volcado de hilo, incluidas las trazas de pila de todos los hilos en ejecución: ¡perfecto! Después de imprimir la información de depuración, Java VM continuará haciendo lo que estaba haciendo antes; de hecho, el volcado de subprocesos ocurre en otro subproceso generado de máxima prioridad. (Puedes probarlo tú mismo usando kill -3 <VM-PID>
).
Tenga en cuenta que también puede registrar sus propios manejadores de señal usando las clases ( SignalHandler
) Signal
y SignalHandler
(¡sin soporte!) En el sun.misc
, para que pueda divertirse con él.
Sin embargo, todavía tengo que encontrar una manera de enviar una señal a un proceso de Windows. Las señales son creadas por ciertas entradas de usuario: Ctrl-C
activa un SIGINT
en ambas plataformas, por ejemplo. Pero no parece haber ninguna utilidad para enviar manualmente una señal a un proceso en ejecución, pero no interactivo en Windows. La solución obvia es usar el ejecutable Cygwin kill
, pero si bien puede finalizar los procesos de Windows utilizando la API de Windows adecuada, no pude enviar un SIGBREAK
(el equivalente de Windows a SIGQUIT
); de hecho, creo que la única señal que puede enviar a los procesos de Windows es SIGTERM
.
Entonces, para resumir una historia larga y repetir el titular: ¿Cómo envío una señal arbitraria a un proceso en Windows?
También puede usar jconsole para ver el stacktrace de todos los subprocesos en ejecución. Esto funcionará en Windows y cualquier otro sistema operativo que admita Java. jconsole también tiene muchas otras funciones agradables, gráficos de memoria, gráficos de CPU, etc.
No responde su pregunta original, pero con suerte le permite obtener los mismos resultados.
Si no está familiarizado con jconsole, consulte la documentación de Uso de JConsole .
Windows no es POSIX. No tiene señales. Las únicas ''señales'' que reciben los programas de la consola son si llaman a SetConsoleCtrlHandler
, en cuyo caso se puede notificar que el usuario ha presionado Ctrl + C, Ctrl + Break, cerrado la ventana de la consola, cerrado la sesión o cerrado el sistema.
Todo lo demás se hace con IPC, generalmente con mensajes de ventana o RPC. Consulte la documentación de Sun para ver si hay una manera de hacer lo que está pidiendo en el JRE de Windows.
Si lo que quieres es eliminar explícitamente / programáticamente otro programa / proceso de cualquier tipo, dentro de las pstools de SysInternals hay una pequeña herramienta llamada "pskill" que se comporta como lo haría Unixen "kill".
Si quieres algo más, sigue leyendo (aunque es posible que me equivoque con algunos de los detalles a continuación; han pasado eones desde la última vez que desarrollé un programa de Windows en C usando solo los excelentes libros de WinAPI y Charles Petzold "Programación para Windows" como guía )
En Windows no tiene "señales" correctamente, qué funciones reciben WinMain y WinProc del sistema operativo son mensajes simples. Por ejemplo, cuando hace clic en el botón "X" de una ventana, Windows envía el manejador de Windows el mensaje WM_CLOSE. Cuando se borra la ventana pero el programa aún se está ejecutando, envía WM_DESTROY. Cuando está a punto de salir del bucle principal de procesamiento de mensajes, WinMain (no WinProc) recibe WM_QUIT. Su programa debe responder a todo esto como se espera: puede desarrollar una aplicación "imposible de cerrar" al no hacer lo que debería al recibir un WM_CLOSE.
Cuando el usuario selecciona la tarea desde el Administrador de tareas de Windows y hace clic en "Finalizar tarea", el sistema operativo enviará WM_CLOSE (y otro que no recuerdo). Sin embargo, si usa "Terminar proceso", el proceso se mata directamente, no se envían mensajes nunca (fuente: The Old New Thing
Recuerdo que había una manera de obtener el HWND de la ventana de otro proceso, una vez que obtienes que otro proceso podría enviar a esa ventana un mensaje a través de las funciones PostMessage y DispatchMessage.
Ruby de alguna manera puede (al menos emular) SIGINT SIGKILL, etc. en Windows, y atrapa esos mensajes. Puede que quieras comprobarlo.
La forma en que Ruby "envía señal SIGINT a ese proceso" debajo, en Windows, es llamar a TerminateProcess
o equivalente en ese PID.
También hay un método equivalente de Windows para "capturar ctrl + c". Me imagino que es lo que allí se llama.
En Windows, todo gira en torno a los mensajes de Win32. No creo que haya una herramienta de línea de comandos para hacer esto, pero en C ++ podría usar FindWindow para enviar un mensaje arbitrario a otro programa de Windows. p.ej:
#define WM_MYMSG ( WM_USER+0x100 )
HWND h = ::FindWindow(NULL,_T("Win32App"));
if (h) {
::PostMessage(h, WM_MYMSG, 0, 0);
}
Esto también se puede hacer en C # usando com interop.