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?
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?
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%
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
@ubi podwójny procent dla pliku bat/cmd, pojedynczy do uruchomienia bezpośrednio na konsoli –
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
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 :) –
Czy robisz to za pomocą języka programowania? Co to jest? – Kaf
Nie działa, jeśli masz wiele instancji z uruchomioną wersją – Titule
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