How to get own process pid from the command prompt in Windows

Solution 1:

Since none of the other solutions are bulletproof and built in, I figured I'd offer the following solution, but note that you'll need to parse/save the results somehow:

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

Solution 2:

Expanding upon Tony Roth's answer:

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

Using the WINDOWTITLE filter avoids the pipe so you can put it in a for loop and assign it to a variable with SET if you like:

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

Removing the /v makes it quicker, and the /NH gets rid of the header line. You need the wildcard after "uniqueTitle" because the window title actually contains the current command (thus it would go on and on if you tried to match it fully).


Solution 3:

Using PowerShell + WMI :

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

Using WMIC :

for /f %a in ('wmic os get LocalDateTime ^| findstr [0-9]') do set NOW=%a
wmic process where "Name='wmic.exe' and CreationDate > '%NOW%'" get ParentProcessId | findstr [0-9]

(as always, double the % sign with for in batch files)


Solution 4:

I believe the following is bulletproof, provided the user has access to WMIC and TEMP points to a valid path where the user has write privileges. This is the end result of some collaborative work at 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

The script establishes an exclusive lock on a temporary file that incorporates the current time into the name. There can only be a collision if two like named batch processes attempt to get the PID within the same 0.01 second time interval, in which case only one will succeed.

Any process that fails will repeatedly loop back and try again with a new lock file path until it succeeds.

The full path to the lock file is transformed into a unique ID that can be used in the WMIC query. WMIC is run within a FOR /F command, which means it is running in a child cmd.exe process. That is why the ParentProcessID of the cmd.exe process is retrieved.


Solution 5:

  1. Windows Task Manager, you will need to go to View -> Select Columns.. and select PID.
  2. "tasklist /v" to get verbose task information in command prompt.
  3. Process Explorer from live.sysinternals.com.