在windows中从命令提示符获取自己的进程pid

问题描述 投票:0回答:6

我正在尝试从它自己的命令提示符中获取 PID。但是当使用下面的命令时,我并不总是得到所需的输出。您能指出以下语句中的错误是什么吗?

cmd.exe /c title="mycmd" & tasklist /v /fo csv | findstr /i "mycmd" & dir & help

编辑:

以下命令工作正常。但是当它与另外两个命令结合使用时。没用。

cmd.exe /c title="mycmd" & tasklist /v /fo csv | findstr /i "mycmd"

附加信息:

我正在使用Java

final List<String> commands = new ArrayList<String>();                

commands.add("cmd.exe");
commands.add("/C");

//.. Add more commands

ProcessBuilder pb = new ProcessBuilder(commands);
java windows cmd
6个回答
4
投票

您可以使用下面的批处理文件获取cmd提示符的PID。

参考:http://social.msdn.microsoft.com/Forums/en-US/msbuild/thread/270f0842-963d-4ed9-b27d-27957628004c/

获取PID.bat

@echo off
if not defined SESSIONNAME set SESSIONNAME=Console
setlocal
set instance=%DATE% %TIME% %RANDOM%
title %instance%
for /f "usebackq tokens=2" %%a in (`tasklist /FO list /FI "SESSIONNAME eq %SESSIONNAME%" /FI "USERNAME eq %USERNAME%" /FI "WINDOWTITLE eq %instance%" ^| find /i "PID:"`)
    do set PID=%%a
if not defined PID for /f "usebackq tokens=2" %%a in (`tasklist /FO list /FI "SESSIONNAME eq %SESSIONNAME%" /FI "USERNAME eq %USERNAME%" /FI "WINDOWTITLE eq Administrator:  %instance%" ^| find /i "PID:"`)
    do set PID=%%a
if not defined PID
 echo !Error: Could not determine the Process ID of the current script.  Exiting.& exit /b 1
echo PID: "%PID%"

1
投票

您需要在要在子 shell 中执行的复合命令两边加上引号:

cmd.exe /c "title="mycmd" & tasklist /v /fo csv | findstr /i "mycmd" & dir & help"

如果没有引号,命令将被解析为

(cmd.exe /c title="mycmd") & (tasklist /v /fo /csv) | (findstr /i "mycmd") & (dir) & (help)

因此,当

tasklist
运行具有指定标题的
cmd.exe
实例时,已经退出。


0
投票

您可能缺少一些重定向运算符。阅读更多这里。


0
投票

为 CMD 窗口指定一个唯一的名称,在本例中为“test”。 “Windowstitle”是“test*”,因为执行的命令行将附加到标题中。

title test
taskkill /FI "IMAGENAME eq cmd.exe" /FI "WINDOWTITLE ne test*" /f

0
投票

我发现我还必须使用带有用户名的域。

    @IF NOT DEFINED SESSIONNAME (@SET SESSIONNAME=Console)
    @SETLOCAL
    @SET EXITCODE=0
    @SET instance=%DATE% %TIME% %RANDOM%
    @TITLE %instance%

    @FOR /F "usebackq tokens=1,2" %%a IN (`tasklist /FO list /FI "SESSIONNAME eq %SESSIONNAME%" /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "WINDOWTITLE eq %instance%" ^| FIND /I "PID:"`) DO @(
        @SET PID=%%b
    )

    @IF NOT DEFINED PID (
        @FOR /F "usebackq tokens=1,2" %%a IN (`tasklist /FO list /FI "SESSIONNAME eq %SESSIONNAME%" /FI "USERNAME eq %USERDOMAIN%\%USERNAME%" /FI "WINDOWTITLE eq Administrator:  %instance%" ^| FIND /I "PID:"`) DO @(
            @SET PID=%%b
        )
    )

    @IF NOT DEFINED PID (
        @ECHO ERROR: Could not determine the Process ID of the current script.
        @SET EXITCODE=1
    ) ELSE (
        @ECHO %PID%
    )

    @EXIT /B %EXITCODE%

0
投票

这是一种优雅且防弹的方法,它利用 PowerShell,并且无法被用户检测到,因为它不需要设置或更改窗口标题(如果在批处理脚本中使用,这一点很重要)。

for /F %a in ('powershell -Command "$tempPID = (Get-WmiObject Win32_Process -Filter ProcessId=$pid).ParentProcessId; (Get-WmiObject Win32_Process -Filter ProcessId=$tempPID).ParentProcessId"') do (set "my_pid=%a")

“$pid”变量存储由 for 循环内的“powershell”命令创建的 PowerShell 进程的 PID。 PowerShell 命令的第一部分 (

$tempPID = (Get-WmiObject Win32_Process -Filter ProcessId=$pid).ParentProcessId
) 获取父进程的 PID 并将其存储到“$tempPID”变量中。但是,该父进程不是主 CMD 窗口,而是由主 CMD 创建的子 cmd.exe 进程。由于某种原因,CMD 总是为每个 for 循环创建一个新的子 cmd.exe 进程,并且主 CMD 是其父进程。所以你实际上需要获取父级的父级的PID。这是通过 PowerShell 命令的第二部分 (
(Get-WmiObject Win32_Process -Filter ProcessId=$tempPID).ParentProcessId
) 完成的。

最后,正确的 PID 被捕获并存储在“my_pid”变量中。

P。 S. 如果您想在批处理脚本中使用该命令,请确保使用双百分号作为标记(“%%a”而不是“%a”)。

© www.soinside.com 2019 - 2024. All rights reserved.