2012-02-28 18 views
20

En las secuencias de comandos por lotes de Windows existe el comando start que inicia un nuevo proceso.¿Cómo obtener el PID del proceso recién iniciado desde un archivo por lotes?

¿Es posible obtener el PID del proceso recién iniciado?

+0

¿Lo hace utilizando un lenguaje de programación? ¿Qué es? – Kaf

+0

No funciona si tiene varias instancias ejecutándose – Titule

+1

Posible duplicado de [Cómo capturar el PID de un proceso al iniciarlo en DOS] (https://stackoverflow.com/questions/1807794/how-to-capture-the- pid-of-a-process-when-launching-it-in-dos) – user

Respuesta

17

Puede hacerlo por lotes pero no directamente, por ejemplo. Necesita analizar el resultado de tasklist.exe o usar wmic.exe. Ambos requieren que sepas lo que acabas de comenzar, lo que por supuesto lo harás.

Usando Tasklist.exe:

for /F "TOKENS=1,2,*" %a in ('tasklist /FI "IMAGENAME eq powershell.exe"') do set MyPID=%b 
echo %MyPID% 

Para utilizar esto en una escritura de la hornada del doble de los signos de porcentaje.

Uso wmic.exe:

for /f "TOKENS=1" %a in ('wmic PROCESS where "Name='powershell.exe'" get ProcessID ^| findstr [0-9]') do set MyPID=%a 
echo %MyPID% 
+1

Esto no funcionó, tuve que agregar un signo '%' adicional antes del '% a' y'% b' en el primer ejemplo y antes de ambos '% a's en el segundo ejemplo. Además, ambos ejemplos me dieron los PID de TODAS las instancias de lo que acabo de iniciar ('powershell.exe' en el ejemplo) en lugar del único PID de la instancia que acabo de iniciar (es decir, si una instancia de' powershell.exe' se estaba ejecutando antes de ejecutar cualquiera de estos ejemplos, también se devolvería su PID). Dicho esto, si desea eliminar TODAS las instancias de una tarea, es más fácil 'taskkill/im powershell.exe/f' – ubiquibacon

+0

@ubi doble por ciento para el archivo bat/cmd, solo para ejecutar directamente en la consola –

10

Si hay procesos ya se está ejecutando con el mismo nombre, primero tiene que obtener una lista de los PIDs actuales, de iniciar su proceso local (es) y a continuación, comprobar los pids de nuevo Aquí hay un código de muestra que inicia el proceso 3 y los elimina al final (específicamente los que se iniciaron localmente):

@echo off 
set PROCESSNAME=notepad.exe 

::First save current pids with the wanted process name 
setlocal EnableExtensions EnableDelayedExpansion 
set "RETPIDS=" 
set "OLDPIDS=p" 
for /f "TOKENS=1" %%a in ('wmic PROCESS where "Name='%PROCESSNAME%'" get ProcessID ^| findstr [0-9]') do (set "OLDPIDS=!OLDPIDS!%%ap") 

::Spawn new process(es) 
start %PROCESSNAME% 
start %PROCESSNAME% 
start %PROCESSNAME% 

::Check and find processes missing in the old pid list 
for /f "TOKENS=1" %%a in ('wmic PROCESS where "Name='%PROCESSNAME%'" get ProcessID ^| findstr [0-9]') do (
if "!OLDPIDS:p%%ap=zz!"=="%OLDPIDS%" (set "RETPIDS=/PID %%a !RETPIDS!") 
) 

::Kill the new threads (but no other) 
taskkill %RETPIDS% /T > NUL 2>&1 
endlocal 
+3

P.S. Por supuesto, esto introduce una condición de carrera si ejecuta múltiples versiones del guión en paralelo. En el caso de la tarea, esto podría ser dañino, ya que un pid una vez asesinado podría ser reasignado a un hilo completamente diferente que no querría que se matara "nuevamente". En ese momento, probablemente no deberías confiar en la sintaxis del lote de Windows de todos modos :) –

Cuestiones relacionadas