24

im trying to find a way to get my own PID from a command prompt (for later use in bat scripts) so far the only useful way i found was to use getpids.exe from here : http://www.scheibli.com/projects/getpids/index.html but im looking for a command that's "built in" to windows

edit : im looking for a "bullet proof" way - no assumptions about my process being the only cmd.exe or anything

12 Answers 12

34

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"
  • thats really neat. im pretty sure the current time + some randomly-generated number can be set as the title to get near bulletproof – radai Mar 29 '10 at 10:49
  • 3
    Don't use %random% + %time% if you have a scheduler call your batch script twice at the same time. I had the issue that the same script was called with different parameters at the same time. The seed for random was the same and I ran into collisions when creating a temporary directory. There was no way around then to handle the error when creating the temporary directory. Long story short, if you can assume that your script does not get fired of twice at the same time, this trick should work. – Peter Schuetze Nov 11 '14 at 17:05
  • Might be (not deeply tested) that getting a more precise timestamp (including microseconds, rather than 1/100 seconds like in %time%), would be more reliable in this case: wmic os get LocalDateTime (YearMonthDayHourMinuteSecond.Microsecond+Timezone). Unless the scheduler is able to run two things in the exact same microsecond... – Gauthier Boaglio Dec 15 '14 at 6:38
  • This won't work if the process is running in another session on the computer as the title is shown as N/A – FrinkTheBrave Feb 3 '16 at 11:19
  • This gives the PID of the parent process. – access_granted Apr 12 '17 at 22:48
7

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.

6

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

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.
  • 1
    @Vivek, from a command prompt... and you are duping answers – WooYek Mar 27 '10 at 0:02
  • i just gave all possible options.. and no duplicating.. i could have also mentioned PowerShell but i restrained myself as that does not comes by default in XP and 2003. If this is for Vista onwards OS, Yes PowerShell would have been my preference. – Vivek Kumbhar Mar 27 '10 at 0:24
5

if you know there's only one cmd.exe running, you can get the PID this way:

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

echo %pid%
  • That sounds like an improbable assumption, your code could be flaky – Raúl Salinas-Monteagudo Jul 9 at 6:48
  • Raul, I understand what you're saying. It's unsafe in many cases, but is safe in some -- such as a kiosk system or a VM where you're in total control of what processes are starting and not – zumalifeguard Jul 9 at 23:24
5

Using PowerShell + WMI :

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

This should do the trick:

tasklist /v

3

If you want to find the PID of imagename "notepad.exe", then the following code will work for you:

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

If you've got the Windows 2003 Resource kit push it through qgrep to get just the line you want. You could then extract the pid from here (this assumes you've only got one cmd running at a time),

tasklist /v | qgrep cmd

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

Take a look at this little batch trick. It sets the title of cmd to a special value then uses tasklist to find it. Inventive

\\Greg

0

THIS IS SHORT WAY TO GET PROCESS ID FOR OPEN CMD

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

This answer will give you ONLY the process ID, and none of the extra stuff the top answer includes.

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%

Explanation:

-there will not be a PID for cmd.exe that is greater than 18100 so check if PID2 is greater than 8100 so we know if it's a 4 digit or 5 digit number

case 1: a 5 digit PID like 17504 has a PID1 val 17504 and a PID2 val of 1750, so we use PID1

case 2: a 4 digit PID like 8205 has a PID1 val of 8205" and a PID2 val of 8205, so we use PID2

case 3: a 4 digit PID like 4352 has a PID1 val of 4352" and a PID2 val of 4352, so we use PID2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.