从命令行启动进程时如何捕获进程的 PID?

发布于 2024-08-13 06:08:43 字数 70 浏览 6 评论 0原文

有没有办法纯粹在 .bat 文件中执行此操作?

目的是启动 iexplore.exe,然后在完成后杀死该实例。

Is there a way to do this purely in a .bat file?

The purpose is to launch iexplore.exe, then kill just that instance when it's finished.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

疯到世界奔溃 2024-08-20 06:08:43

这是我使用的:

@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

Here's what I use:

@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

The directory is set to the directory that the cmd file is located in. Change dir to alter that. Modify cmd to change which command is run.

If you want a stop.cmd that kills it, it would look like this

@echo off
for /F %%i in (%~dsp0MyProg.pid) do taskkill /F /PID %%i
del %~dsp0MyProg.pid
偏爱自由 2024-08-20 06:08:43

您可以使用 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

you can use vbscript, here's an example creating notepad, then terminating it using its 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 

save as myscript.vbs and on command line

c:\test> cscript /nologo myscript.vbs
他是夢罘是命 2024-08-20 06:08:43

@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

A slight variation on the answer provided by @kybernetikos since it has a parsing issue. Note the line 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
胡渣熟男 2024-08-20 06:08:43

大多数情况下,您确实知道要启动什么任务 - 在这种情况下,iexplorer 将显示哪个页面。

那么,

taskkill /FI "Windowtitle eq *yourpagetitle*"

它会杀死显示页面标题的所有实例,但对于特定的标题,最常见的是应该有一个。

汤姆

Most often you do know what task you start - in this case, which page iexplorer shall show.

So how about

taskkill /FI "Windowtitle eq *yourpagetitle*"

It will kill all instances of something showing your page title, but with a specific title most often there should be exactly one.

Tom

落日海湾 2024-08-20 06:08:43

由于某种原因,您获取进程 ID 的方法对我来说不起作用,但由于我是批量专家,所以我编写了自己的方法,附在此处:

@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

For some reason your approach of getting process id did not work for me, but since I'm expert in batches, I've coded my own approach, attaching here:

@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
我不是你的备胎 2024-08-20 06:08:43

PowerShell 可用于此目的:

powershell -executionPolicy bypass -command "& {$process = start-process $args[0] -passthru -argumentlist $args[1..($args.length-1)]; exit $process.id}" notepad test.txt

echo Process ID of new process: %errorlevel%

PowerShell can be used for this:

powershell -executionPolicy bypass -command "& {$process = start-process $args[0] -passthru -argumentlist $args[1..($args.length-1)]; exit $process.id}" notepad test.txt

echo Process ID of new process: %errorlevel%
病毒体 2024-08-20 06:08:43

我认为你不能用简单的命令行实用程序来做到这一点,因为 IE 实际上会为每个选项卡生成子进程,即如果 IE 尚未运行,你将获得一个父 IE 进程和该选项卡的一个子进程,如果 IE 是已经运行的你只会得到一个子进程。

当你编写自己的工具来杀死 IE 时,这甚至会非常棘手,因为当你杀死一个子(选项卡)进程时,IE 会自动恢复该选项卡。

另请参阅此相关问题:如何获取新创建的 IE8 的进程窗口?(尽管没有好的答案)。

I think you can't do that with simple command line utilities, as IE actually spawns child processes for each tab, i.e. if IE is not yet running you would get one parent IE process and a child process for the tab, and if IE is already running you would simply get a single child process.

It will be even quite tricky when you write your own tool to kill IE because when you kill a child (tab) process, IE will automatically recover this tab.

See also this related question: How to obtain process of newly created IE8 window? (though there is no good answer there).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文