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

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"

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é.


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).


6

Utilisation de PowerShell + WMI:

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

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 .

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%

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


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%

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

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


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:"

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.