Batch file 运行批处理脚本时获取cmd的Pid

Batch file 运行批处理脚本时获取cmd的Pid,batch-file,process,cmd,echo,Batch File,Process,Cmd,Echo,这应该很简单,但我没能找到 若我在cmd中运行一些批处理脚本,那个么如何获取托管cmd的进程id set currentCmdPid= /* some magic */ echo %currentCmdPid% 我发现很多解决方案都使用了任务列表和名称过滤,但我相信这对我来说不起作用,因为可以启动许多cmd实例 同样,我想要一些简单、优雅、防弹的解决方案 谢谢。这里已经讨论了这个主题-> 以下是我的解决方案: @if (@X)==(@Y) @end /* JScript comment @ec

这应该很简单,但我没能找到

若我在cmd中运行一些批处理脚本,那个么如何获取托管cmd的进程id

set currentCmdPid= /* some magic */
echo %currentCmdPid%
我发现很多解决方案都使用了
任务列表
和名称过滤,但我相信这对我来说不起作用,因为可以启动许多cmd实例

同样,我想要一些简单、优雅、防弹的解决方案


谢谢。

这里已经讨论了这个主题->

以下是我的解决方案:

@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);

这里讨论的主题是->

以下是我的解决方案:

@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);
这是由测试结果得出的结果

@echo关闭
:getPID[RtnVar]
::
::将当前运行脚本的进程ID(PID)存储在环境变量中
::RtnVar。如果调用时没有任何参数,那么只需将PID写入标准输出。
::
setlocal disableDelayedExpansion
:getLock
设置“lock=%temp%\%~nx0.%time::=.%.lock”
设置“uid=%lock:\=:b%”
设置“uid=%uid:,=:c%”
设置“uid=%uid:”=:q%
设置“uid=%uid:\=:u%”
setlocal enableDelayedExpansion
设置“uid=!uid:%%=:p!”
endlocal&设置“uid=%uid%”
2> nul(9>%lock%)(
对于/f“跳过=1”%%A,在(
'wmic进程,其中“name='cmd.exe'和命令行类似“%%%”获取ParentProcessID'
)(%%A)中%%B的do设置为“PID=%%B”
(电话)
))||goto:getLock
删除“%lock%”2>nul
endlocal&如果“%$1”eq”“(回显(%PID%)else设置“%$1=%PID%”
退出/b
在与批处理脚本相同的文件夹中安装exe文件(编译的JScript)

在我的机器上,我的纯批处理getPID运行速度比Npcmaka的exe快20%。这是因为exe首先确定自己的进程PID,这需要很长时间,然后才使用WMI确定所需的父PID。我的脚本生成唯一ID(快得多)它被合并到确定所需父PID的WMIC调用中

在这两种解决方案中,大部分时间都花在WMI中,在WMI中它确定特定进程的父PID。

以下是由WMI导致的

@echo关闭
:getPID[RtnVar]
::
::将当前运行脚本的进程ID(PID)存储在环境变量中
::RtnVar。如果在没有任何参数的情况下调用,则只需将PID写入stdout即可。
::
setlocal disableDelayedExpansion
:getLock
设置“lock=%temp%\%~nx0.%time::=.%.lock”
设置“uid=%lock:\=:b%”
设置“uid=%uid:,=:c%”
设置“uid=%uid:”=:q%
设置“uid=%uid:\=:u%”
setlocal enableDelayedExpansion
设置“uid=!uid:%%=:p!”
endlocal&设置“uid=%uid%”
2> nul(9>%lock%)(
对于/f“跳过=1”%%A,在(
'wmic进程,其中“name='cmd.exe'和命令行类似“%%%”获取ParentProcessID'
)(%%A)中%%B的do设置为“PID=%%B”
(电话)
))||goto:getLock
删除“%lock%”2>nul
endlocal&如果“%$1”eq”“(回显(%PID%)else设置“%$1=%PID%”
退出/b
在与批处理脚本相同的文件夹中安装exe文件(编译的JScript)

在我的机器上,我的纯批处理getPID运行速度比Npcmaka的exe快20%。这是因为exe首先确定自己的进程PID,这需要很长时间,然后才使用WMI确定所需的父PID。我的脚本生成唯一ID(快得多)它被合并到确定所需父PID的WMIC调用中


在这两种解决方案中,大部分时间都花在WMI中,WMI确定特定进程的父进程PID。

要获取cmd PID,请从cmd运行powershell并获取父进程Id——这将是cmd PID。脚本获取父进程的父进程(因为
FOR/F
调用另一个cmd.exe)


要获取cmd PID,我从cmd运行powershell并获取父进程Id——这将是cmd PID。Script获取父进程的父进程(因为
FOR/F
调用另一个cmd.exe)


嗯,这并不简单,但我想无论如何。为什么这对Windwos来说如此困难:(这是一件非常简单和常见的事情。如果cmd环境通过环境变量暴露于它自己的进程信息,那就太好了,不是吗?不管怎样,你获取当前控制台的PID的目的是什么?如果你用它来锁定进程,。用它来查找
cmd.exe
的PID。它比Npcmaka或m更快。)ine.npocmaka给我指出dbenham的位置仍然得到+1.:)如果您想捕获正在启动的进程的PID,而不是
cmd
本身的PID。最简单的解决方案是
调用:spawn wrapper.bat
,并将wrapper.bat的内容设置为
@app.exe>path\to\log.txt
。或者您可以硬编码
wmic进程调用创建“%args:=\”%>path\\to\\log.txt”
。无论哪种方式,您都必须完全限定
c:\path\to\log.txt
。我认为
wmic process call create
使用
%systemroot%\system32
作为其工作目录。我不知道如何在不引用它的情况下将
作为
调用
参数的一部分传递,因此我无法建议您如何包含重定向与
调用
相同。用插入符号转义
在我的测试中似乎没有任何效果。嗯,这并不简单,但我认为无论如何。为什么这对Windwos如此困难:(这是一件非常简单和常见的事情。如果cmd环境通过环境变量暴露于它自己的进程信息,那就太好了,不是吗?不管怎样,你获取当前控制台的PID的目的是什么?如果你用它来锁定进程,。用它来查找
cmd.exe
的PID。它比Npcmaka或m更快。)ine.npocmaka给我指出dbenham的位置仍然得到+1.:)如果您想捕获正在启动的进程的PID,而不是
cmd
本身的PID。最简单的解决方案是
调用:spawn wrapper.bat
,并将wrapper.bat的内容设置为
@app.exe>path\to\log.txt
。或者您可以硬编码
wmic进程调用创建“%args:=\”%>path\\to\\log.txt”
。无论哪种方式,您都必须完全限定
c:\path\to\log.txt
。我认为
wmic进程调用create
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%