cómo obtener un proceso propio pid desde el símbolo del sistema en windows


26

Estoy tratando de encontrar una manera de obtener mi propio PID desde un símbolo del sistema (para su uso posterior en scripts de bat) hasta ahora, la única forma útil que encontré fue usar getpids.exe desde aquí: http://www.scheibli.com/ projects / getpids / index.html pero estoy buscando un comando que esté "integrado" en Windows

editar: estoy buscando una forma "a prueba de balas" - no hay suposiciones acerca de que mi proceso sea el único cmd.exe o algo

Respuestas:


36

Como ninguna de las otras soluciones son a prueba de balas y están integradas, pensé que ofrecería la siguiente solución, pero tenga en cuenta que tendrá que analizar / guardar los resultados de alguna manera:

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

Eso es realmente genial. Estoy bastante seguro de que la hora actual + algún número generado aleatoriamente se puede establecer como el título para acercarse a prueba de balas
radai

3
No use% random% +% time% si tiene un planificador que llame a su secuencia de comandos por lotes dos veces al mismo tiempo. Tuve el problema de que se llamaba al mismo script con diferentes parámetros al mismo tiempo. La semilla para el azar fue la misma y me encontré con colisiones al crear un directorio temporal. No había forma de evitar el error al crear el directorio temporal. En pocas palabras, si puede suponer que su guión no se dispara dos veces al mismo tiempo, este truco debería funcionar.
Peter Schuetze

Podría ser (no probado en profundidad) que obtener una marca de tiempo más precisa (incluyendo microseconds, en lugar de 1/100 segundos, como en% time%), sería más confiable en este caso: wmic os get LocalDateTime(YearMonthDayHourMinuteSecond.Microsecond + Timezone). A menos que el planificador pueda ejecutar dos cosas exactamente en el mismo microsegundo ...
Gauthier Boaglio

Esto no funcionará si el proceso se ejecuta en otra sesión en la computadora ya que el título se muestra como N / A
FrinkTheBrave

Esto proporciona el PID del proceso padre.
access_granted

7

Creo que lo siguiente es a prueba de balas, siempre que el usuario tenga acceso a puntos WMIC y TEMP a una ruta válida donde el usuario tenga privilegios de escritura. Este es el resultado final de un trabajo de colaboración en 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

El script establece un bloqueo exclusivo en un archivo temporal que incorpora la hora actual en el nombre. Solo puede haber una colisión si dos procesos por lotes con nombre intentan obtener el PID dentro del mismo intervalo de tiempo de 0.01 segundos, en cuyo caso solo uno tendrá éxito.

Cualquier proceso que falle repetidamente repetirá e intentará nuevamente con una nueva ruta de archivo de bloqueo hasta que tenga éxito.

La ruta completa al archivo de bloqueo se transforma en una ID única que se puede utilizar en la consulta WMIC. WMIC se ejecuta dentro de un comando FOR / F, lo que significa que se ejecuta en un proceso hijo cmd.exe. Es por eso que se recupera el ParentProcessID del proceso cmd.exe.


7

Ampliando la respuesta de Tony Roth:

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

El uso del filtro WINDOWTITLE evita la tubería para que pueda colocarlo en un bucle for y asignarlo a una variable con SET si lo desea:

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

Eliminarlo lo /vhace más rápido y /NHelimina la línea de encabezado. Necesita el comodín después "uniqueTitle"porque el título de la ventana realmente contiene el comando actual (por lo tanto, seguiría y seguiría si intentara coincidir completamente).


6

Usando PowerShell + WMI:

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

Agradable; si tiene PowerShell Core , se pone aún más fácil (aunque ninguno de comandos será rápida ):pwsh -noprofile -c "(Get-Process -Id $PID).Parent.Id"
mklement

5
  1. Administrador de tareas de Windows, deberá ir a Ver -> Seleccionar columnas ... y seleccionar PID.
  2. "tasklist / v" para obtener información detallada de la tarea en el símbolo del sistema.
  3. Explorador de procesos de live.sysinternals.com .

2
@Vivek, desde un símbolo del sistema ... y estás
duplicando

Acabo de dar todas las opciones posibles ... y no duplicar ... También podría haber mencionado PowerShell pero me contuve ya que eso no viene por defecto en XP y 2003. Si esto es para el sistema operativo Vista en adelante, sí, PowerShell hubiera sido mi preferencia .
Vivek Kumbhar

5

si sabe que solo hay un cmd.exe ejecutándose, puede obtener el PID de esta manera:

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

echo %pid%

Eso suena como una suposición improbable, su código podría ser falso
Raúl Salinas-Monteagudo

Raúl, entiendo lo que estás diciendo. Es inseguro en muchos casos, pero es seguro en algunos, como un sistema de quiosco o una máquina virtual donde usted tiene el control total de los procesos que se inician y no
zumalifeguard


3

Si desea encontrar el PID del nombre de la imagen "notepad.exe", el siguiente código funcionará para usted:

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

2

Si tiene el kit de recursos de Windows 2003, introdúzcalo en qgrep para obtener la línea que desea. Luego puede extraer el pid desde aquí (esto supone que solo tiene un cmd ejecutándose a la vez),

tasklist /v | qgrep cmd

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


0

ESTA ES LA FORMA CORTA DE OBTENER ID DE PROCESO PARA ABRIR CMD

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

0

Esta respuesta le dará SOLAMENTE la identificación del proceso, y ninguna de las cosas adicionales que incluye la respuesta principal.

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%

Explicación:

-no habrá un PID para cmd.exe que sea mayor que 18100, así que verifique si PID2 es mayor que 8100 para saber si es un número de 4 o 5 dígitos

caso 1: un PID de 5 dígitos como 17504 tiene un PID1 val 17504 y un PID2 val de 1750, por lo que usamos PID1

caso 2: un PID de 4 dígitos como 8205 tiene un valor PID1 de 8205 "y un valor PID2 de 8205, por lo que utilizamos PID2

caso 3: un PID de 4 dígitos como 4352 tiene un valor PID1 de 4352 "y un valor PID2 de 4352, por lo que usamos PID2

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.