How to capture the PID of a process when launching it from command line?

前端 未结 8 1891
栀梦
栀梦 2020-11-30 13:48

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.

相关标签:
8条回答
  • 2020-11-30 14:18

    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
    
    0 讨论(0)
  • 2020-11-30 14:20

    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
    
    0 讨论(0)
  • 2020-11-30 14:26

    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).

    0 讨论(0)
  • 2020-11-30 14:39

    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
    
    0 讨论(0)
  • 2020-11-30 14:40

    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
    
    0 讨论(0)
  • 2020-11-30 14:43

    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

    0 讨论(0)
提交回复
热议问题