comment obtenir son propre pid de processus à partir de l'invite de commande dans Windows

26

im essayant de trouver un moyen d'obtenir mon propre PID à partir d'une invite de commande (pour une utilisation ultérieure dans les scripts de chauve-souris) jusqu'à présent, le seul moyen utile que j'ai trouvé était d'utiliser getpids.exe à partir d'ici: http://www.scheibli.com/ projects / getpids / index.html mais je cherche une commande "intégrée" à Windows

edit: je cherche un moyen "à l'épreuve des balles" - aucune hypothèse sur mon processus étant le seul cmd.exe ou quoi que ce soit

radai
la source

Réponses:

36

Étant donné qu'aucune des autres solutions n'est à l'épreuve des balles et intégrée, j'ai pensé proposer la solution suivante, mais notez que vous devrez analyser / enregistrer les résultats d'une manière ou d'une autre:

title mycmd
tasklist /v /fo csv | findstr /i "mycmd"
Tony Roth
la source
c'est vraiment bien. Je suis sûr que l'heure actuelle + un certain nombre généré aléatoirement peut être défini comme le titre pour se rapprocher des balles
radai
3
N'utilisez pas% random% +% time% si vous avez un planificateur qui appelle votre script batch deux fois en même temps. J'ai eu le problème que le même script était appelé avec différents paramètres en même temps. La graine pour random était la même et j'ai rencontré des collisions lors de la création d'un répertoire temporaire. Il n'y avait alors aucun moyen de gérer l'erreur lors de la création du répertoire temporaire. Pour faire court, si vous pouvez supposer que votre script n'est pas renvoyé deux fois en même temps, cette astuce devrait fonctionner.
Peter Schuetze
Peut-être (non testé en profondeur) qu'obtenir un horodatage plus précis (y compris microseconds, plutôt que 1/100 secondes comme en% time%), serait plus fiable dans ce cas: wmic os get LocalDateTime(YearMonthDayHourMinuteSecond.Microsecond + Timezone). A moins que l'ordonnanceur soit capable d'exécuter deux choses exactement dans la même microseconde ...
Gauthier Boaglio
Cela ne fonctionnera pas si le processus s'exécute dans une autre session sur l'ordinateur car le titre est affiché comme N / A
FrinkTheBrave
Cela donne le PID du processus parent.
access_granted
7

Je crois que ce qui suit est à l'épreuve des balles, à condition que l'utilisateur ait accès aux points WMIC et TEMP vers un chemin valide où l'utilisateur a des privilèges d'écriture. Il s'agit du résultat final d'un travail collaboratif sur 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

Le script établit un verrou exclusif sur un fichier temporaire qui incorpore l'heure actuelle dans le nom. Il ne peut y avoir collision que si deux processus par lots nommés similaires tentent d'obtenir le PID dans le même intervalle de temps de 0,01 seconde, auquel cas un seul réussira.

Tout processus qui échoue sera répété en boucle et réessayera avec un nouveau chemin de fichier de verrouillage jusqu'à ce qu'il réussisse.

Le chemin d'accès complet au fichier de verrouillage est transformé en un ID unique qui peut être utilisé dans la requête WMIC. WMIC est exécuté dans une commande FOR / F, ce qui signifie qu'il s'exécute dans un processus enfant cmd.exe. C'est pourquoi le ParentProcessID du processus cmd.exe est récupéré.

dbenham
la source
7

Développant la réponse de Tony Roth:

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

L'utilisation du filtre WINDOWTITLE évite le tuyau, vous pouvez donc le placer dans une boucle for et l'affecter à une variable avec SET si vous le souhaitez:

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

La suppression de la /vrend plus rapide et la /NHsupprime la ligne d'en-tête. Vous avez besoin du caractère générique après "uniqueTitle"parce que le titre de la fenêtre contient en fait la commande actuelle (ainsi il continuerait si vous essayiez de le faire correspondre complètement).

David
la source
6

Utilisation de PowerShell + WMI:

powershell (Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId
Nicolas Melay
la source
Agréable; si vous avez PowerShell Core , cela devient encore plus facile (bien qu'aucune des commandes ne soit rapide ):pwsh -noprofile -c "(Get-Process -Id $PID).Parent.Id"
mklement
5
  1. Windows Task Manager, vous devrez aller dans Affichage -> Sélectionner les colonnes .. et sélectionner PID.
  2. "tasklist / v" pour obtenir des informations détaillées sur les tâches dans l'invite de commande.
  3. Explorateur de processus de live.sysinternals.com .
Vivek Kumbhar
la source
2
@Vivek, à partir d'une invite de commande ... et vous
dupez
je viens de donner toutes les options possibles .. et pas de duplication .. j'aurais aussi pu mentionner PowerShell mais je me suis retenu car cela ne vient pas par défaut dans XP et 2003. Si c'était pour Vista à partir du système d'exploitation, oui PowerShell aurait été ma préférence .
Vivek Kumbhar
5

si vous savez qu'il n'y a qu'un seul cmd.exe en cours d'exécution, vous pouvez obtenir le PID de cette façon:

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

echo %pid%
zumalifeguard
la source
Cela ressemble à une hypothèse improbable, votre code pourrait être floconneux
Raúl Salinas-Monteagudo
Raul, je comprends ce que tu dis. C'est dangereux dans de nombreux cas, mais est sûr dans certains - comme un système de kiosque ou une machine virtuelle où vous êtes en contrôle total des processus qui démarrent et non
zumalifeguard
4

Cela devrait faire l'affaire:

liste des tâches / v

WooYek
la source
3

Si vous souhaitez trouver le PID du nom imag "notepad.exe", le code suivant fonctionnera pour vous:

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

Si vous avez le kit de ressources Windows 2003, faites-le passer par qgrep pour obtenir uniquement la ligne souhaitée. Vous pouvez ensuite extraire le pid à partir d'ici (cela suppose que vous n'avez qu'un seul cmd en cours d'exécution à la fois),

tasklist /v | qgrep cmd

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

Jetez un œil à cette petite astuce de lot . Il définit le titre de cmd sur une valeur spéciale puis utilise la liste des tâches pour le trouver. Inventif

\\ Greg

uSlackr
la source
0

CECI EST COURT POUR OBTENIR UN ID DE PROCESSUS POUR UN CMD OUVERT

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

Cette réponse vous donnera UNIQUEMENT l'ID du processus, et aucun des éléments supplémentaires inclus dans la réponse du haut.

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%

Explication:

-il n'y aura pas de PID pour cmd.exe supérieur à 18100, donc vérifiez si PID2 est supérieur à 8100 afin que nous sachions s'il s'agit d'un nombre à 4 ou 5 chiffres

cas 1: un PID à 5 chiffres comme 17504 a un PID1 val 17504 et un PID2 val de 1750, nous utilisons donc PID1

cas 2: un PID à 4 chiffres comme 8205 a une valeur PID1 de 8205 "et une valeur PID2 de 8205, nous utilisons donc PID2

cas 3: un PID à 4 chiffres comme 4352 a une valeur PID1 de 4352 "et une valeur PID2 de 4352, nous utilisons donc PID2

Collin Fox
la source