这应该很简单但我找不到它。
如果我在cmd中运行一些批处理脚本,我如何获取托管cmd的进程ID?
set currentCmdPid= /* some magic */
echo %currentCmdPid%
我找到了许多使用tasklist
和名称过滤的解决方案,但我相信这对我来说不起作用,因为可以启动许多cmd实例。
同样,我想要一些简单优雅且防弹的解决方案。
感谢。
答案 0 :(得分:2)
以下是my pure batch script version生成的same DosTips discussion and collaborative effort that npocmaka referenced。
@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
npocmaka's solution将exe文件(已编译的JScript)安装在与批处理脚本相同的文件夹中。
在我的机器上,我的纯批量getPID运行速度比npocmaka的exe快20%!这是因为在使用WMI确定所需的父PID之前,exe首先确定自己的进程PID,这需要很长的时间。我的脚本生成一个唯一的ID(更快),它被合并到确定所需父PID的WMIC调用中。
在这两种解决方案中,大部分时间都花在WMI中,它确定特定进程的父PID。
答案 1 :(得分:1)
此处讨论的主题 - &gt; http://www.dostips.com/forum/viewtopic.php?p=38870
这是我的解决方案:
@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
set "jsc=%%v"
)
if not exist "%~n0.exe" (
"%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)
%~n0.exe
endlocal & exit /b %errorlevel%
*/
import System;
import System.Diagnostics;
import System.ComponentModel;
import System.Management;
var myId = Process.GetCurrentProcess().Id;
var query = String.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId);
var search = new ManagementObjectSearcher("root\\CIMV2", query);
var results = search.Get().GetEnumerator();
if (!results.MoveNext()) {
Console.WriteLine("Error");
Environment.Exit(-1);
}
var queryObj = results.Current;
var parentId = queryObj["ParentProcessId"];
var parent = Process.GetProcessById(parentId);
Console.WriteLine(parent.Id);
答案 2 :(得分:0)
为了获取 cmd PID,我从 cmd 运行 powershell 并获取父进程 ID——这将是 cmd PID。脚本获取父级的父级(因为 FOR /F
调用另一个 cmd.exe)。
FOR /F "tokens=* USEBACKQ" %%F IN (`powershell -c "(gwmi win32_process | ? processid -eq ((gwmi win32_process | ? processid -eq $PID).parentprocessid)).parentprocessid"`) DO (
SET PCT_CleanAfterPID=%%F
)
ECHO %PCT_CleanAfterPID%