2009-04-29 11 views
9

Mam aplikację java, która używa ProcessBuilder do przygotowania polecenia systemu operacyjnego i daje mi obiekt Process. (Prawdziwym komendą os jest rsync przez ssh używając cygwin).Java ProcessBuilder process.destroy() nie zabija procesów potomnych w winXP

Działa to dobrze w systemie Windows, jednak jeśli chcę zatrzymać proces za pomocą process.destroy(), to nie zabije procesów potomnych ssh i rsync ..... Muszę je ręcznie zabić za pomocą menedżera zadań Windows.

Czy można uzyskać OutputStream procesu i wysłać ctrl-c w jakiś sposób, zanim zadzwonię pod numer destroy();?

Jeśli ktoś ma jakieś pomysły na obejście tego problemu, byłoby świetnie. Dzięki, D

+1

Ctrl-C jest funkcją terminalową, która wysyła sygnał (SIGTERM?) Do identyfikatora procesu. Aby emulować, że potrzebujesz identyfikatora procesu i móc wysłać sygnał, wywołanie funkcji –

Odpowiedz

5

Uważam także, że emulacja Ctrl-C w celu całkowitego zabicia ssh jest problematyczna.

Co mogę zrobić, to jedno z następujących podejść. Użyj poleceń systemu Windows, aby dowiedzieć się, kto jest synem ssh (co jest trochę problematyczne, ponieważ musisz znać swój bieżący pid, aby otrzymać własne procesy-dzieci). Wierzę, że pstools z sysinternals jest dobrym narzędziem wiersza polecenia, które powinno umożliwić śledzenie procesów osieroconych. Zobacz this example do sterowania procesami Windows z taskList.exe (która może dać ci wyjście w formacie CSV BTW) lub poprzez wykonanie specjalnego VBScript.

Drugie podejście polega na użyciu biblioteki Java, takiej jak winp, aby wykonać i kontrolować proces ssh. Wierzę, że mógłbyś wymienić wszystkie swoje dzieci i zabić ich siłą, jeśli przesłanie poprawnej wiadomości nie byłoby wystarczające. To byłoby moje preferowane podejście. Należy pamiętać, że metoda killRecursively robi dokładnie to, co chcesz.

Należy pamiętać, że te metody nie powinny powodować wyświetlania tylko okien aplikacji. Można je zaliczyć do klasy, która działa inaczej na systemach Windows i na maszynach typu Linux.

Proszę zauważyć, że nie próbowałem uzyskać szczegółowej kontroli nad procesami Windows, więc nie jestem pewien, jak dojrzałe byłyby te rozwiązania, które znalazłem.

+0

Wydaje się, że winp zyskał na popularności i jest częścią Hudson (w rzeczywistości został napisany w tym celu). Adres URL java.net nie rozwiązuje więcej, ale oryginalny artykuł nadal istnieje na https://weblogs.java.net/blog/kohsuke/archive/2008/03/introducing_win.html (zauważ, że niektóre z tych informacji są datowane, jak tylko 32-bitowe). Nowy adres URL dla winp (z linkami do mvn i github) to: http://winp.kohsuke.org/ – toddkaufmann

+0

@toddkaufmann dzięki, zaktualizowałam URL. –

0

Nie jestem pewien, co Process.destroy() ma pod kołdrą (wysyła sygnał lub podobne?).

To, co możesz znaleźć, działa lepiej, to wywołanie ssh/rsync w skrypcie powłoki i zwrócenie identyfikatora procesu na stdout, a następnie, gdy chcesz zabić proces, wykonaj /bin/kill z tym identyfikatorem procesu. Trochę niechlujny, ale może bardziej niezawodny.

Pamiętaj, że możesz /bin/kill z SIGTERM i SIGKILL, jeśli jest szczególnie uparty.

+2

Process.destroy() wywołuje funkcję Windows TerminateProcess (http://msdn.microsoft.com/en-us/library/ms686714(VS .85) .aspx). –

Powiązane problemy