如何从Windows中的命令提示符获取自己的进程pid


26

我试图找到一种方法来从命令提示符中获取我自己的PID(以供以后在bat脚本中使用),到目前为止,我发现的唯一有用的方法是从此处使用getpids.exe:http : //www.scheibli.com/ projects / getpids / index.html但我正在寻找“内置”到Windows的命令

编辑:我正在寻找一种“项目符号证明”的方式-没有关于我的过程是唯一的cmd.exe或任何假设

Answers:


36

由于没有其他解决方案是防弹和内置的,因此我认为我将提供以下解决方案,但是请注意,您需要以某种方式解析/保存结果:

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

那真的很整齐。我很确定可以将当前时间+一些随机生成的数字设置为标题以接近防​​弹效果
radai

3
如果您有一个调度程序,请不要同时使用%random%+%time%两次调用批处理脚本。我遇到的问题是,同一脚本同时使用不同的参数调用。随机种子是一样的,创建临时目录时遇到冲突。创建临时目录时,无法解决该错误。长话短说,如果您可以假设您的脚本没有被同时解雇两次,那么这个技巧应该可以奏效。
Peter Schuetze 2014年

microseconds在这种情况下,可能(未经深度测试)会得到更精确的时间戳(包括,而不是像%time%中那样为1/100秒),该时间戳会更可靠:wmic os get LocalDateTime(YearMonthDayHourMinuteSecond.Microsecond + Timezone)。除非调度程序能够在完全相同的微秒内运行两件事...
Gauthier Boaglio 2014年

如果进程正在计算机上的另一个会话中运行,则将无法正常工作,因为标题显示为N / A
FrinkTheBrave '16

这给出了父进程的PID。
access_granted

7

我相信以下内容是防弹的,只要用户可以访问WMIC和TEMP即可指向用户具有写权限的有效路径。这是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

该脚本在临时文件上建立排他锁,该文件将当前时间合并到名称中。仅当两个类似的命名批处理进程试图在相同的0.01秒时间间隔内获取PID时,才会发生冲突,在这种情况下,只有一个成功。

任何失败的进程都将反复循环返回,并使用新的锁定文件路径再试一次,直到成功为止。

锁定文件的完整路径将转换为可在WMIC查询中使用的唯一ID。WMIC在FOR / F命令中运行,这意味着它在子cmd.exe进程中运行。这就是为什么要检索cmd.exe进程的ParentProcessID的原因。


7

扩展托尼·罗斯的答案:

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

使用WINDOWTITLE过滤器可避免使用管道,因此您可以将其置于for循环中,并根据需要将其分配给SET变量:

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

删除它/v可以使其更快,并且/NH摆脱标题行。之后需要通配符,"uniqueTitle"因为窗口标题实际上包含当前命令(因此,如果您尝试完全匹配它,它将继续存在)。


6

使用PowerShell + WMI:

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

不错 如果您具有PowerShell Core,它将变得更加容易(尽管两个命令都不会很快):pwsh -noprofile -c "(Get-Process -Id $PID).Parent.Id"
mklement

5
  1. Windows Task Manager,您将需要转到View-> Select Columns ..并选择PID。
  2. “任务列表/ v”以在命令提示符下获取详细的任务信息。
  3. 来自live.sysinternals.com的 Process Explorer 。

2
@Vivek,从命令提示符...而您正在欺骗答案
WooYek 2010年

我只是给出了所有可能的选择..并且没有重复..我也可以提到PowerShell,但是我克制自己,因为在XP和2003中默认情况下不会出现这种情况。 。
Vivek Kumbhar,2010年

5

如果您知道只有一个cmd.exe在运行,则可以通过以下方式获取PID:

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

echo %pid%

这就像一个不可能的假设的声音,你的代码可能是片状
劳尔·萨利纳斯,蒙特阿古

劳尔,我明白你在说什么。在许多情况下这是不安全的,但在某些情况下是安全的-例如信息亭系统或VM,您可以完全控制启动哪些进程而不是完全由它们控制
zumalifeguard


3

如果要查找图像名称为“ notepad.exe”的PID,则以下代码将为您工作:

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

2

如果您有Windows 2003资源工具包,请通过qgrep推送它,以获取所需的行。然后,您可以从此处提取pid(假设您一次只运行一个cmd),

tasklist /v | qgrep cmd

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

1

看一下这个小技巧。它将cmd的标题设置为特殊值,然后使用任务列表进行查找。有创造力的

格雷格


0

这是获取开放CMD的过程ID的捷径

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

0

该答案仅会给您进程ID,而顶级答案中没有任何多余的东西。

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%

说明:

-cmd.exe不会有大于18100的PID,因此请检查PID2是否大于8100,以便我们知道它是4位还是5位数字

情况1:像17504这样的5位数PID的PID1值17504和PID2值1750,因此我们使用PID1

情况2:像8205这样的4位数PID的PID1值是8205“,而PID2值是8205,所以我们使用PID2

情况3:像4352这样的4位数PID的PID1值是4352“,PID2值是4352,所以我们使用PID2

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.