Как перехватить PID процесса при запуске из командной строки? - PullRequest
10 голосов
/ 27 ноября 2009

Есть ли способ сделать это чисто в файле .bat?

Цель - запустить iexplore.exe, а затем убить только тот экземпляр, когда он будет завершен.

Ответы [ 7 ]

10 голосов
/ 23 июля 2012

Вот что я использую:

@echo off

rem there is a tab in the file at the end of the line below
set tab=    
set cmd=javaw -jar lib\MyProg.jar
set dir=%~dp0

echo Starting MyProg
set pid=notfound

for /F "usebackq tokens=1,2 delims=;=%tab% " %%i in (
    `wmic process call create "%cmd%"^, "%dir%"`
) do (
    if /I %%i EQU ProcessId (
        set pid=%%j
    )
)

echo %pid% > MyProg.pid

В качестве каталога задан каталог, в котором находится cmd-файл. Измените dir, чтобы изменить его. Измените cmd, чтобы изменить, какая команда выполняется.

Если вы хотите, чтобы файл stop.cmd убил его, он бы выглядел следующим образом

@echo off
for /F %%i in (%~dsp0MyProg.pid) do taskkill /F /PID %%i
del %~dsp0MyProg.pid
3 голосов
/ 27 ноября 2009

вы можете использовать vbscript, вот пример создания блокнота с последующим его завершением при помощи pid

strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process")
errReturn = objProcess.Create("notepad.exe", null, objConfig, PID)
If errReturn = 0 Then
    WScript.Echo "Process ID is: " & PID
End If 

WScript.Echo "Ready to kill process: " & PID & "? [Y|y]"
Do While Not WScript.StdIn.AtEndOfLine
   strInput = strInput & WScript.StdIn.Read(1)
Loop
If LCase(strInput) = "y" Then
    WScript.Echo "Select * from Win32_Process Where ProcessId = '" & PID & "'"
    Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where ProcessId = '" & PID & "'")
    For Each objProcess in colProcessList
        objProcess.Terminate()
    Next
End If 

сохранить как myscript.vbs и в командной строке

c:\test> cscript /nologo myscript.vbs
2 голосов
/ 17 октября 2017

Чаще всего вы знаете, какую задачу запускаете - в данном случае, какую страницу должен показать iexplorer.

Так как насчет

taskkill /FI "Windowtitle eq *yourpagetitle*"

Это уничтожит все экземпляры чего-либо, показывающие заголовок вашей страницы, но с определенным заголовком чаще всего должен быть ровно один.

Tom

2 голосов
/ 02 августа 2015

Небольшое отклонение от ответа, предоставленного @kybernetikos, поскольку у него есть проблема с анализом. Обратите внимание на строку if %%j gr 0 (

@echo off

rem there is a tab in the file at the end of the line below
set tab=    
set cmd=javaw -jar lib\MyProg.jar
set dir=%~dp0

echo Starting MyProg
set pid=notfound

for /F "usebackq tokens=1,2 delims=;=%tab% " %%i in (
    `wmic process call create "%cmd%"^, "%dir%"`
) do (
    if %%j gtr 0 (
        set pid=%%j
    )
)

echo %pid% > MyProg.pid
2 голосов
/ 27 ноября 2009
1 голос
/ 01 мая 2013

По какой-то причине ваш подход к получению идентификатора процесса у меня не сработал, но, поскольку я разбираюсь в партиях, я кодировал свой собственный подход, добавив сюда:

@echo off

call:AsyncCmd
rem call:AsyncCmd "echo hello world"
rem call:AsyncCmd "call build.bat"
exit /b

rem ------------------------------------------------------------------------------------------
rem Starts asynchronous command execution 
rem %1 is command, if empty - only aborts existing build.
rem ------------------------------------------------------------------------------------------
:AsyncCmd
if exist %~dp0SetupBuild_Completed.txt (
    del /f %~dp0SetupBuild_Pid.txt >nul 2>&1
    del /f %~dp0SetupBuild_Completed.txt >nul 2>&1
)

if not exist %~dp0SetupBuild_Pid.txt goto lStartProc
    rem --------------------------------------------------
    rem Abort build process
    rem --------------------------------------------------
    set /p pid=<%~dp0SetupBuild_Pid.txt
    echo Cancelling setup build process, process id %pid%
    pskill -t %pid%
    del /f %~dp0SetupBuild_Pid.txt >nul 2>&1

:lStartProc
if "%~1" == "" exit /b 0

rem --------------------------------------------------
rem Starts asyncronous build process
rem --------------------------------------------------
set dir=%~dp0
set dir=%dir:~0,-1%
for /f "tokens=2 delims==; " %%a in ('wmic process call create "cmd /c mincon.exe && %~1 && echo 1>%~dp0SetupBuild_Completed.txt"^, "%dir%" ^| findstr /r "ProcessId"') do set pid=%%a
echo Setup build started, process id: %pid%
echo %pid%>%~dp0SetupBuild_Pid.txt
exit /b 0
0 голосов
/ 27 ноября 2009

Я думаю, что вы не можете сделать это с помощью простых утилит командной строки, поскольку IE фактически порождает дочерние процессы для каждой вкладки, то есть, если IE еще не запущен, вы получите один родительский процесс IE и дочерний процесс для вкладки, и если IE уже запущен, вы просто получите один дочерний процесс.

Даже если вы напишите собственный инструмент для уничтожения IE, будет довольно сложно, потому что, когда вы убиваете дочерний процесс (вкладка), IE автоматически восстанавливает эту вкладку.

См. Также этот связанный вопрос: Как получить процесс недавно созданного окна IE8? (хотя там нет хорошего ответа).

...