标题: [系统相关] [已解决]批处理如何获取自身进程的PID? [打印本页]
作者: BAT-VBS 时间: 2013-1-18 13:24 标题: [已解决]批处理如何获取自身进程的PID?
本帖最后由 BAT-VBS 于 2013-1-19 11:01 编辑
http://www.bathome.net/thread-4066-1-1.html
这个帖子里面的代码不靠谱,因为系统里面可能不止一个cmd.exe进程在运行。
作者: batman 时间: 2013-1-18 14:20
好像链接中有你想要的答案啊。。。- @echo off
- set "mpath=%~0"
- wmic process where commandline='cmd /c ""%mpath:\=\\%" "' get processid
- pause>nul
复制代码
作者: terse 时间: 2013-1-18 14:21
本帖最后由 terse 于 2013-1-18 14:23 编辑
除非你多次运行 否则应该满足的
我的意思是 PATH 是单一的 就单一“PATH” 文件运行 应是唯一的
作者: BAT-VBS 时间: 2013-1-18 17:06
回复 2# batman
C:\Test>test.bat
无可用范例。
XP SP3 原版系统
作者: BAT-VBS 时间: 2013-1-18 17:07
回复 3# terse
太高深看不懂。
比如我随便打开一个cmd窗口,然后再双击运行test.bat,如果根据cmd.exe的进程来获取pid,很显然是会出错的吧。
作者: CrLf 时间: 2013-1-18 17:28
- wmic process where name="wmic.exe" get parentprocessid
复制代码
作者: terse 时间: 2013-1-18 20:08
回复 5# BAT-VBS
首先每次运行TEST.bat都将得到不同PID 运行一次 将得到TEST.bat进程 PID
你可以先运行名称非TEST的其他BAT文件
再运行TEST.bat 得到的仍是TEST.bat进程 PID
当然有另一情况 那就是 你连续运行两次以上TEST.bat 那你将得到多个 TEST.bat 进程 PID
以下内容为 TEST.bat- @echo off
- set path_=%0
- for /f "usebackq skip=1" %%i in (`"wmic process where commandline='cmd /c "%path_:\=\\% "' get processID"`) do echo %%i
- pause
复制代码
作者: BAT-VBS 时间: 2013-1-18 21:50
回复 7# terse
测试结果见4楼,不知道是我的系统有问题,还是这个方法不通用。
作者: BAT-VBS 时间: 2013-1-18 21:50
回复 6# CrLf
版主V5
作者: BAT-VBS 时间: 2013-1-18 22:10
我自己写了一个tasklist,不知道是否通用。- @echo off
- for /f "tokens=2" %%a in ('tasklist /v ^| findstr /c:"- %0"') do (
- echo %%a
- )
- pause
复制代码
作者: BAT-VBS 时间: 2013-1-18 22:20
回复 6# CrLf
版主,我发现一个问题。把wmic放到bat文件里面之后,它获取的pid并非此bat的pid,是不是wmic在执行的时候自己会先创建一个子进程?- @echo off
- for /f "tokens=2 delims==" %%a in ('wmic process where "name='wmic.exe'" get parentprocessid /value') do (
- set "myPid=%%a"
- )
- echo,%myPid%
- pause
复制代码
作者: CrLf 时间: 2013-1-19 03:56
回复 11# BAT-VBS
for /f 从命令中获取输入时,实际上是执行了一个 %comspec% /c xxxxxx,待进程退出后解析其输出,所以如果在 for /f 中执行 wmic 获得的将是 for /f 所创建的 cmd.exe 进程 pid。
要想通过 for /f 获取当前进程 pid,在原方案的基础上有三个延伸方案
1、用临时文件避免产生多余进程- wmic process where name="wmic.exe" get parentprocessid>tmp.txt
- for /f "skip=1" %%a in (tmp.txt) do echo %%a
复制代码
2、利用管道的特性,直接解析外部命令输出- wmic process where name="wmic.exe" get parentprocessid|for /f "skip=1" %%a in ('more') do echo %%a
复制代码
3、先获取 for /f 产生的进程pid- for /f "skip=1" %%a in ('"@for /f "skip=1" %%p in ('wmic process where name^="wmic.exe" get parentprocessid') do @wmic process where processid="%%p" get parentprocessid"') do echo %%a
复制代码
但是鉴于 wmic 无论在 xp 还是 win7 下输出都带有多余的回车符,所以建议在解析时这样过滤一下:- for /f %%a in ('copy /z "%~0" nul') do set "回车符=%%a"
- for /f "delims=%回车符%" %%a in ("wmic的输出.txt") echo %%a
复制代码
除了通过父进程 pid 和 batman 以脚本路径为依据的办法,还可以通过标题栏来获取:- set "title=%random%"
- title %title%
- tasklist /fi "windowtitle eq %title%"
- ::如果是以管理员权限运行的,则是 tasklist /fi "windowtitle eq 管理员: %title%*"
复制代码
作者: BAT-VBS 时间: 2013-1-19 11:00
回复 12# CrLf
感谢大神,学习了。
作者: tmplinshi 时间: 2013-1-19 13:36
2、利用管道的特性,直接解析外部命令输出
wmic process where name="wmic.exe" get parentprocessid|for /f "skip=1" %%a in ('more') do echo %%a ...
CrLf 发表于 2013-1-19 03:56
在管道后面使用 for 以前没想到。学习了。
作者: terse 时间: 2013-1-19 14:04
本帖最后由 terse 于 2013-1-22 15:47 编辑
总感觉 通过父进程得到pid 还是要确认路径的 才可靠
原来确定父进程pid是FOR输出是 for /f 所创建的 cmd.exe 进程 pid
所以错误的认为非路径确认 学习了 解析输出
所以 否定上面 “总感觉 通过父进程得到pid 还是要确认路径的 才可靠” !
作者: CrLf 时间: 2013-1-19 16:29
回复 14# tmplinshi
管道法来自这里:http://bbs.bathome.net/redirect. ... 1&fromuid=30406
作者: Pale_Cheung 时间: 2013-11-17 13:06
本帖最后由 Pale_Cheung 于 2013-11-17 13:09 编辑
回复 BAT-VBS
for /f 从命令中获取输入时,实际上是执行了一个 %comspec% /c xxxxxx,待进程退出 ...
CrLf 发表于 2013-1-19 03:56
windowtitle 局限性是 本 session 里。比如别的远程桌面上的会话,session 0 的(服务,包括计划任务)取不到他们的windowtitle。本session也有些是暂缺。
其他的方法还是收获不小啊。
powershell 倒是有变量直接解决这个问题了。
作者: cjiabing 时间: 2013-11-17 14:43
http://www.bathome.net/viewthread.php?tid=11052
[原创] 批处理与进程
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |