2012-02-28 18 views
20

W skryptach wsadowych w systemie Windows jest polecenie start, które uruchamia nowy proces.Jak uzyskać PID procesu właśnie rozpoczęty z wewnątrz pliku wsadowego?

Czy można uzyskać PID właśnie rozpoczętego procesu?

+0

Czy robisz to za pomocą języka programowania? Co to jest? – Kaf

+0

Nie działa, jeśli masz wiele instancji z uruchomioną wersją – Titule

+1

Możliwy duplikat [Sposób przechwytywania identyfikatora PID procesu podczas uruchamiania go w systemie DOS] (https://stackoverflow.com/questions/1807794/how-to-capture-the- pid-of-a-process-when-launching-it-in-dos) – user

Odpowiedz

17

Można w partii, ale nie bezpośrednio na powiedzieć. Musisz przeanalizować dane wyjściowe pliku tasklist.exe lub użyć narzędzia wmic.exe. Oba wymagają, abyś wiedział, co właśnie zacząłeś, co oczywiście będziesz.

Korzystanie tasklist.exe:

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

Aby to wykorzystać w skrypcie podwoić znaki procent.

Korzystanie 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

To nie działało dla mnie, musiałem dodać dodatkowy znak '%' przed '% a' i'% b' w pierwszy przykład i przed obydwoma '% a's w drugim przykładzie. Dodatkowo, oba przykłady dały mi PID-y WSZYSTKICH wystąpień rzeczy, którą właśnie rozpocząłem ("powershell.exe" w przykładzie) zamiast pojedynczego PID instancji, którą właśnie rozpocząłem (tj. Jeśli instancja 'powershell.exe' był uruchomiony, zanim którykolwiek z tych przykładów został uruchomiony, jego PID również zostanie zwrócony). Mówiąc to, jeśli chcesz zabić WSZYSTKIE instancje zadania, łatwiej jest 'taskkill/im powershell.exe/f' – ubiquibacon

+0

@ubi podwójny procent dla pliku bat/cmd, pojedynczy do uruchomienia bezpośrednio na konsoli –

10

Jeśli istnieją już uruchomione procesy o tej samej nazwie, trzeba najpierw uzyskać listę bieżących PID, niż rozpocząć proces lokalny (ES), a następnie sprawdzić ponownie. Oto przykładowy kod, który rozpoczyna 3 procesy i zabija je na końcu (w szczególności te uruchomione lokalnie):

@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. Oczywiście wprowadza to stan wyścigowy, jeśli równolegle wykonuje się wiele wersji skryptu. W przypadku taskkill może to być szkodliwe, ponieważ raz zabity pid może zostać ponownie przypisany do zupełnie innego wątku, którego nie chcesz, aby został zabity "ponownie". Na tym etapie nie powinieneś chyba polegać na składni wsadowej Windowsa :) –

Powiązane problemy