perl - Cómo matar un árbol de procesos en Windows
winapi process (3)
Hola, tengo este árbol de procesos:
La captura de pantalla de arriba muestra un árbol de proceso. En mi script de Perl, conozco el PID de dscli. He escrito el siguiente código para matar un solo PID:
use Win32::Process;
use strict;
use warnings;
if(defined($ARGV[0])){
my $pid = "$ARGV[0]";
my $exitcode = 0;
Win32::Process::KillProcess($pid, $exitcode);
}else{
print "No argument provided :(/n";
}
El problema es que en mi script no conozco el PID del proceso de Java. Tengo que obtener el PID hijo de dscli, que es el proceso de Java. Si elimino el PID de dscli usando el código anterior, entonces el niño (java) no muere con él.
Entonces mi pregunta es, ¿cómo puedo matar el proceso java que es hijo de dscli usando perl?
Es posible usar WMI desde PERL . WMI puede encontrar el PID de todos los procesos secundarios de un padre determinado . Tenga en cuenta la consulta "select * from win32_process where ParentProcessId={0}"
. Si tiene la lista de PID secundarios, puede llamar a Win32::Process::KillProcess
.
Puede usar el comando de Windows TASKKILL /T
para finalizar un proceso y sus procesos secundarios.
$pid = ...;
system("TASKKILL /F /T /PID $pid");
También te sugiero usar WMI, pero tal vez quieras simplemente llamar a un VBScript desde tu Perl. Aquí hay un script que utilizo para matar por línea de comandos, que puede ayudarlo a reducir un proceso específico de java basado en otras cosas que estaban en la línea de comando cuando se lanzó:
If WScript.Arguments.Count = 1 Then
strProcess = WScript.Arguments.Item(0)
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!//" & strComputer & "/root/cimv2")
Set objShell = CreateObject("WScript.Shell")
Set colProcessList = objWMIService.ExecQuery _
("Select * from Win32_Process")
If colProcessList.Count > 0 Then
For Each objItem in colProcessList
If InStr(objItem.CommandLine, strProcess) Then
If (InStr(objItem.CommandLine, "cscript")) Then
Else
WScript.StdOut.Write objItem.Name + " "
objItem.Terminate()
End If
End If
Next
Else
WScript.StdOut.Write "No instances found running"
End If
Else
WScript.StdOut.Write "Bad Arguments"
End If
Ejecútelo así:
CScript whatEverYouNameIt.vbs "somethingInCommandLineLikeAClassName"