我每次启动工作PC时都会使用批处理文件。基本上,它会杀死IT部门在PC上运行的所有英国媒体软件,这些文件作为我的用户帐户运行,我从未使用taskkill
,安装一个小程序,然后一次加载我实际需要的所有程序。问题是,我运行的程序之一,IT部门最近认为安装"帮助程序"程序自动化我已经知道如何做的程序内的一些东西,并可以手动相当快速地完成。问题是,辅助程序实际上具有相反的效果并且减慢了实际程序的速度。我们当然向IT抱怨它,但它可能需要花费几个月的时间来修复它,如果有的话。与此同时,我发现帮助程序在我的用户帐户下运行它自己的进程,这意味着我可以杀死它,一切运行顺利。问题是程序是如何运行的。我正常启动程序,这种情况发生了:
处理A加载。流程A加载流程B.流程A自行终止。流程B加载流程C.流程C加载流程D,E和F(辅助程序)。进程B自杀,同时将C,D,E和F留在内存中(此时程序已满载)
在继续执行taskkill
命令以终止进程D,E和F之前,如何让批处理文件等待进程B自行终止?由于命令行在直接调用EXE时只看到进程A,因此它会在一秒钟内恢复批处理文件,因为A会快速自杀。我不能仅使用timeout
或其他一些通用时间浪费,因为程序的加载时间太不稳定,网络问题,程序更新等等。
答案 0 :(得分:0)
然而,它应该相当简单,并且将沿着这些方向(只是调整代码以使其工作或让我知道是否有任何问题;我无法测试它但应该能够修复他们,如果我知道他们是什么):
rem Usage: :killprocesswithwait [pid]
call :killprocesswithwait 1234
:killprocesswithwait
set pid=%1
taskkill /pid %pid%
:iloop
ping 127.0.0.1 -n 2 > nul
for /f "tokens=*" %%a in ('tasklist /fi "PID eq %pid%" ^| find /i %pid%') do (
if /i "%%a"=="" (
goto :eof
) else (
goto :iloop
)
)
答案 1 :(得分:0)
等待任何和所有程序退出并检查是否记事本,如果是,则重新启动它。
等待三个程序开始肯定会更好。将Win32_ProcessStopTrace
更改为Win32_ProcessStartTrace
。
Set WshShell = WScript.CreateObject("WScript.Shell")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_ProcessStopTrace")
Do
Set objReceivedEvent = objEvents.NextEvent
msgbox objReceivedEvent.ProcessName
If lcase(objReceivedEvent.ProcessName) = lcase("Notepad.exe") then
Msgbox "Process exited with exit code " & objReceivedEvent.ExitStatus
WshShell.Run "c:\Windows\notepad.exe", 1, false
End If
Loop
这会列出进程并终止任何被调用的计算器。
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")
For Each objItem in colItems
'msgbox objItem.ProcessID & " " & objItem.CommandLine
If objItem.name = "Calculator.exe" then objItem.terminate
Next
答案 2 :(得分:0)
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q36241667.txt"
SET "filename2=%sourcedir%\q36241667_2.txt"
:dloop
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
tasklist|FIND "%%a" >NUL
IF ERRORLEVEL 1 timeout /t 1 >nul&GOTO dloop
)
FOR /f "usebackqdelims=" %%a IN ("%filename2%") DO ECHO(%%a
GOTO :EOF
您需要更改sourcedir
的设置以适合您的具体情况。
我使用了名为q36241667.txt
&的文件q36241667_2.txt
包含一些虚拟数据供我测试。
假设filename1
包含
processa.exe
processb.exe
processc.exe
processd.exe
processe.exe
然后for
循环将等到所有进程都在运行之后再继续。
filename2
包含所需的kill命令(echo
用于演示目的)
如果此例程在启动例程中只是start
,那么它本身可以触发start
命令来终止任何不需要的进程。
我使用类似的例程在启动时将关键目录备份到ramstick。
答案 3 :(得分:0)
谢谢大家,我实际上接受了Ruslan的回答并进行了简化并稍微改了一下。这非常有效。等待exe3加载,因为它是最后一个加载,然后杀死所有3.不需要设置变量以便删除那些并完全忘记将它放入循环中。
:start
FOR /F %%x IN ('tasklist /NH /FI "IMAGENAME eq exe3.exe"') DO IF %%x == exe3.exe goto found
goto start
:found
taskkill /f /fi "blah1.exe"
taskkill /f /fi "blah2.exe"
taskkill /f /fi "blah3.exe"