Batch file 运行批处理脚本时获取cmd的Pid
这应该很简单,但我没能找到 若我在cmd中运行一些批处理脚本,那个么如何获取托管cmd的进程idBatch 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
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%