2009-04-29 22 views
9

Tengo una aplicación java que usa ProcessBuilder para preparar un comando del sistema operativo y me da un objeto Process. (El comando real os es rsync sobre ssh usando cygwin).Java ProcessBuilder process.destroy() no mata procesos secundarios en winXP

Esto funciona bien en Windows, sin embargo, si quiero detener el proceso usando process.destroy(), no se matarán los procesos secundarios ssh y rsync ..... Tengo que matarlos manualmente usando el administrador de tareas de Windows.

¿Es posible obtener el OutputStream del proceso y enviar un ctrl-c de alguna manera antes de llamar al destroy();?

Si alguien tiene alguna idea sobre una solución, sería genial. Gracias, D

+1

La Ctrl-C es una función de terminal que envía una señal (SIGTERM?) A la identificación del proceso. Entonces, para emular que necesitaría la identificación del proceso y poder enviar una señal –

Respuesta

5

También creo que emular Ctrl-C para matar a ssh por completo es problemático.

Lo que haría, es uno de los siguientes enfoques. Utilice los comandos de Windows para averiguar quiénes son los hijos de ssh (lo que es un poco problemático, ya que necesita conocer su pid actual para recibir sus propios procesos secundarios). Creo que pstools de sysinternals es una buena herramienta de línea de comandos que debería permitirle rastrear procesos huérfanos. Consulte this example para controlar los procesos de Windows con taskList.exe (que puede darle su resultado en formato CSV BTW) o mediante la ejecución de un VBScript especial.

El segundo enfoque es utilizar una biblioteca java como winp para ejecutar y controlar el proceso ssh. Creo que podrías hacer una lista de todos sus hijos y matarlos a la fuerza si enviar el mensaje correcto no fuera suficiente. Este sería mi enfoque preferido. Tenga en cuenta que el método killRecursively hace exactamente lo que desea.

Tenga en cuenta que esos enfoques no deben representar solo las ventanas de su aplicación. Puede encapsular los de una clase que se ejecutaría de forma diferente en Windows y Linux.

Tenga en cuenta que no traté de obtener un control detallado sobre los procesos de Windows con, por lo que no estoy seguro de qué tan maduras serían esas soluciones que encontré.

+0

winp parece haber crecido en popularidad, y es parte de Hudson (en realidad, fue escrito para ello). La URL de java.net ya no se resuelve, pero el artículo original todavía existe en https://weblogs.java.net/blog/kohsuke/archive/2008/03/introducing_win.html (tenga en cuenta que parte de esa información es fechado, como solo 32 bits). La nueva URL para winp (con enlaces a mvn y github) es: http://winp.kohsuke.org/ – toddkaufmann

+0

@toddkaufmann gracias, actualizó la URL. –

0

No estoy seguro de qué hace Process.destroy() debajo de las coberturas (¿envía una señal o similar?).

Lo que puede encontrar que funciona mejor es invocar su ssh/rsync dentro de un script de shell, y hacer que devuelva un id de proceso en stdout, y luego cuando quiera matar el proceso, realice un /bin/kill con ese ID de proceso. Un poco desordenado, pero tal vez más confiable.

Tenga en cuenta que puede /bin/kill con SIGTERM, y SIGKILL si es particularmente obstinado.

+2

Process.destroy() llama a la función de Windows TerminateProcess (http://msdn.microsoft.com/en-us/library/ms686714(VS) .85) .aspx). –

Cuestiones relacionadas