come ottenere il proprio processo pid dal prompt dei comandi in Windows


26

sto cercando di trovare un modo per ottenere il mio PID da un prompt dei comandi (per un uso successivo negli script di pipistrello) finora l'unico modo utile che ho trovato è stato quello di utilizzare getpids.exe da qui: http://www.scheibli.com/ progetti / getpids / index.html ma sto cercando un comando "integrato" in Windows

modifica: sto cercando un modo "a prova di proiettile" - nessuna ipotesi sul fatto che il mio processo sia l'unico cmd.exe o altro

Risposte:


36

Poiché nessuna delle altre soluzioni è a prova di proiettile e integrata, ho pensato che avrei offerto la seguente soluzione, ma nota che in qualche modo dovrai analizzare / salvare i risultati:

title mycmd
tasklist /v /fo csv | findstr /i "mycmd"

è davvero pulito. sono abbastanza sicuro che l'ora corrente + alcuni numeri generati casualmente possano essere impostati come titolo per avvicinarsi ai proiettili
radai

3
Non utilizzare% random% +% time% se si dispone di un programmatore che chiama lo script batch due volte contemporaneamente. Ho avuto il problema che lo stesso script è stato chiamato con parametri diversi contemporaneamente. Il seme per casuale era lo stesso e mi sono imbattuto in collisioni durante la creazione di una directory temporanea. Non c'era quindi modo di gestire l'errore durante la creazione della directory temporanea. Per farla breve, se puoi presumere che la tua sceneggiatura non venga licenziata due volte allo stesso tempo, questo trucco dovrebbe funzionare.
Peter Schuetze,

Potrebbe essere (non profondamente testato) che ottenere un timestamp più preciso (incluso microseconds, anziché 1/100 secondi come in% time%), sarebbe più affidabile in questo caso: wmic os get LocalDateTime(YearMonthDayHourMinuteSecond.Microsecond + Timezone). A meno che il programmatore non sia in grado di eseguire due cose nello stesso esatto microsecondo ...
Gauthier Boaglio,

Questo non funzionerà se il processo è in esecuzione in un'altra sessione sul computer poiché il titolo è mostrato come N / A
FrinkTheBrave,

Questo dà il PID del processo genitore.
access_granted

7

Credo che quanto segue sia a prova di proiettile, a condizione che l'utente abbia accesso ai punti WMIC e TEMP su un percorso valido in cui l'utente ha i privilegi di scrittura. Questo è il risultato finale di alcuni lavori collaborativi su http://www.dostips.com/forum/viewtopic.php?f=3&t=6133 .

@echo off

:getPID  [RtnVar]
::
:: Store the Process ID (PID) of the currently running script in environment variable RtnVar.
:: If called without any argument, then simply write the PID to stdout.
::
setlocal disableDelayedExpansion
:getLock
set "lock=%temp%\%~nx0.%time::=.%.lock"
set "uid=%lock:\=:b%"
set "uid=%uid:,=:c%"
set "uid=%uid:'=:q%"
set "uid=%uid:_=:u%"
setlocal enableDelayedExpansion
set "uid=!uid:%%=:p!"
endlocal & set "uid=%uid%"
2>nul ( 9>"%lock%" (
  for /f "skip=1" %%A in (
    'wmic process where "name='cmd.exe' and CommandLine like '%%<%uid%>%%'" get ParentProcessID'
  ) do for %%B in (%%A) do set "PID=%%B"
  (call )
))||goto :getLock
del "%lock%" 2>nul
endlocal & if "%~1" equ "" (echo(%PID%) else set "%~1=%PID%"
exit /b

Lo script stabilisce un blocco esclusivo su un file temporaneo che incorpora l'ora corrente nel nome. Ci può essere una collisione solo se due processi batch denominati simili tentano di ottenere il PID entro lo stesso intervallo di tempo di 0,01 secondi, nel qual caso solo uno riuscirà.

Qualsiasi processo che ha esito negativo tornerà ripetutamente e riproverà con un nuovo percorso del file di blocco fino a quando non avrà esito positivo.

Il percorso completo del file di blocco viene trasformato in un ID univoco che può essere utilizzato nella query WMIC. WMIC viene eseguito all'interno di un comando FOR / F, il che significa che è in esecuzione in un processo cmd.exe figlio. Questo è il motivo per cui viene recuperato ParentProcessID del processo cmd.exe.


7

Espandendo la risposta di Tony Roth:

title uniqueTitle
for /f "tokens=2 USEBACKQ" %f IN (`tasklist /NH /FI "WINDOWTITLE eq uniqueTitle*"`) Do echo %f

L'uso del filtro WINDOWTITLE evita la pipe in modo da poterlo inserire in un ciclo for e assegnarlo a una variabile con SET se ti piace:

title uniqueTitle
for /f "tokens=2 USEBACKQ" %f IN (`tasklist /NH /FI "WINDOWTITLE eq uniqueTitle*"`) Do set ourPID=%f

La rimozione del /vrende più veloce e /NHsi elimina la riga di intestazione. È necessario il carattere jolly dopo "uniqueTitle"perché il titolo della finestra contiene effettivamente il comando corrente (quindi andrebbe avanti e avanti se si cercasse di abbinarlo completamente).


6

Utilizzando PowerShell + WMI:

powershell (Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId

Bello; se hai PowerShell Core , diventa ancora più semplice (anche se nessuno dei due comandi sarà veloce ):pwsh -noprofile -c "(Get-Process -Id $PID).Parent.Id"
mklement

5
  1. Task Manager di Windows, dovrai andare su Visualizza -> Seleziona colonne ... e selezionare PID.
  2. "tasklist / v" per ottenere informazioni dettagliate sull'attività nel prompt dei comandi.
  3. Process Explorer da live.sysinternals.com .

2
@Vivek, da un prompt dei comandi ... e stai
duplicando le

ho appena dato tutte le opzioni possibili ... e nessuna duplicazione .. avrei potuto menzionare anche PowerShell ma mi sono trattenuto in quanto non viene fornito per impostazione predefinita in XP e 2003. Se questo fosse per Vista in poi OS, Sì PowerShell sarebbe stata la mia preferenza .
Vivek Kumbhar il

5

se sai che è in esecuzione solo un cmd.exe, puoi ottenere il PID in questo modo:

for /F "tokens=1,2" %%i in ('tasklist /FI "IMAGENAME eq cmd.exe" /fo table /nh') do set pid=%%j

echo %pid%

Sembra un'ipotesi improbabile, il tuo codice potrebbe essere traballante
Raúl Salinas-Monteagudo

Raul, capisco quello che stai dicendo. Non è sicuro in molti casi, ma è sicuro in alcuni - come un sistema kiosk o una VM in cui hai il controllo totale di quali processi stanno iniziando e non
zumalifeguard

4

Questo dovrebbe fare il trucco:

elenco attività / v


3

Se vuoi trovare il PID di imagename "notepad.exe", il seguente codice funzionerà per te:

for /F "tokens=1,2" %i in ('tasklist') do (
 if "%i" equ "notepad.exe" (set x=%j)
)
echo %x%

2

Se hai il kit di risorse di Windows 2003, invialo attraverso qgrep per ottenere solo la linea che desideri. Puoi quindi estrarre il pid da qui (questo presuppone che tu abbia un solo cmd in esecuzione alla volta),

tasklist /v | qgrep cmd

cmd.exe 2040 RDP-Tcp#447 0 1,804 K Running MACHINE\Administrator  0:00:00 Command Prompt

1

Dai un'occhiata a questo piccolo trucco in lotti . Imposta il titolo di cmd su un valore speciale, quindi utilizza l'elenco delle attività per trovarlo. inventivo

\\ Greg


0

QUESTO È IL MODO CORTO PER OTTENERE L'ID DEL PROCESSO PER CMD APERTO

tasklist /v /fi "imagename EQ cmd.exe" /FO LIST | FIND "PID:"

0

Questa risposta ti darà SOLO l'ID del processo e nessuna delle cose extra incluse nella risposta principale.

title mycmd
tasklist /v /fo csv | findstr /i "mycmd" > PIDinfo.txt

set /p PIDinfo=<PIDinfo.txt
set PID1=%PIDinfo:~11,5%
set PID2=%PIDinfo:~11,4%

if %PID2% gtr 8100 (
    set PID=%PID2%
) else (
    set PID=%PID1%
)

echo %PID%

Spiegazione:

-non ci sarà un PID per cmd.exe maggiore di 18100, quindi controlla se PID2 è maggiore di 8100, quindi sappiamo se è un numero di 4 o 5 cifre

caso 1: un PID a 5 cifre come 17504 ha una PID1 val 17504 e una PID2 val di 1750, quindi usiamo PID1

caso 2: un PID a 4 cifre come 8205 ha una val PID1 di 8205 "e una val PID2 di 8205, quindi usiamo PID2

caso 3: un PID a 4 cifre come 4352 ha un valore PID1 di 4352 "e un valore PID2 di 4352, quindi utilizziamo PID2

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.