Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 批处理文件等待其他进程完成,然后继续_Windows_Batch File_Taskkill - Fatal编程技术网

Windows 批处理文件等待其他进程完成,然后继续

Windows 批处理文件等待其他进程完成,然后继续,windows,batch-file,taskkill,Windows,Batch File,Taskkill,我有一个批处理文件,每次启动我的工作电脑时都会用到。基本上,它会杀死it部门放在电脑上作为我的用户帐户运行的所有臃肿软件,我甚至从未使用过taskkill,安装一个小程序,然后立即加载我实际需要的所有程序。问题是,我运行的其中一个程序,IT部门最近认为安装一个“助手”程序将有助于自动化程序中的一些事情,我已经知道如何操作,并且可以相当快地手动操作。问题是,helper程序实际上具有相反的效果,并减慢了实际程序的速度。我们当然在向它抱怨,但如果有可能的话,他们可能需要几个月的时间来修复它。同时,我

我有一个批处理文件,每次启动我的工作电脑时都会用到。基本上,它会杀死it部门放在电脑上作为我的用户帐户运行的所有臃肿软件,我甚至从未使用过
taskkill
,安装一个小程序,然后立即加载我实际需要的所有程序。问题是,我运行的其中一个程序,IT部门最近认为安装一个“助手”程序将有助于自动化程序中的一些事情,我已经知道如何操作,并且可以相当快地手动操作。问题是,helper程序实际上具有相反的效果,并减慢了实际程序的速度。我们当然在向它抱怨,但如果有可能的话,他们可能需要几个月的时间来修复它。同时,我发现helper程序在我的用户帐户下作为自己的进程运行,这意味着我可以杀死它,并且一切都再次顺利运行。问题是,程序如何运行。我正常启动该程序,并发生以下情况:

处理一个负载。进程A加载进程B。进程A自杀。进程B加载进程C。进程C加载进程D、E和F(助手程序)。进程B自杀,同时将C、D、E和F留在内存中(此时程序已完全加载)


在继续执行
taskkill
命令终止进程D、E和F之前,如何让批处理文件等待进程B自行终止?由于命令行仅在直接调用EXE时看到进程A,因此它会在不到一秒钟的时间内恢复批处理文件,因为A会很快自行终止。我不能只使用
timeout
或其他一些通用的时间浪费器,因为程序的加载时间太不稳定,网络问题、程序更新等等。

几年前,我构建了类似的东西,但不幸的是,我身上没有代码,目前无法访问Windows机器

但是,它应该相当简单,并且将遵循以下原则(只要调整代码使其工作,或者让我知道是否存在任何问题;我无法测试它,但如果我知道它们是什么,应该能够修复它们):


这将等待any和all程序退出并检查记事本是否存在,如果存在则重新启动记事本

当然,最好等到这三个项目开始。将
Win32\u ProcessStopTrace
更改为
Win32\u 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
@ECHO关闭
SETLOCAL
设置“sourcedir=U:\sourcedir”
设置“filename1=%sourcedir%\q36241667.txt”
设置“filename2=%sourcedir%\q3624167_2.txt”
:dloop
对于/f“usebackqdelims=“%%a IN”(“%filename1%”)DO(
任务列表|查找“%%a”>NUL
如果错误级别1超时/T1>nul和GOTO dloop
)
对于/f“usebackqdelims=““%filename2%”中的%%a”执行回显(%%a
后藤:EOF
您需要更改
sourcedir
的设置以适应您的环境

我使用了名为
q3624167.txt
q3624167_2.txt
的文件,其中包含一些用于测试的虚拟数据

假设
filename1
包含

processa.exe
processb.exe
processc.exe
processd.exe
processe.exe
然后,for循环将等待所有进程运行后再继续

filename2
包含所需的kill命令(
echo
ed用于演示)

如果此例程只是在启动例程中设置了
start
ed,那么它本身可能会触发
start
命令来终止任何不需要的进程


我在启动时使用类似的例程将关键目录备份到ramstick上。

谢谢各位,我实际上接受了Ruslan的答案,并对其进行了简化和更改。这非常有效。等待exe3加载,因为它是最后一个加载的,然后杀死所有3个。不需要设置变量,所以删除了这些变量,完全忘记了putti把它做成一个循环

: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"

您可能需要查看SysInternals
PsKill
实用程序:
-t终止进程及其子体。
链接:
taskkill
可以使用/t开关终止进程及其分布式。进程C是实际的程序,需要保持打开状态。此外,加载所有进程后,没有任务层次结构剩余。
过程C是实际的程序,需要保持打开状态。
好。
没有剩余的任务层次结构。
D、E、F不是一个层次结构吗?或者我误解了这个问题?也许我对启动过程D、E和F的原因不正确(也许是B启动了它们?),但当使用Process Explorer查看流程层次结构时,在程序启动并运行后,它不会显示C、D、E、F的活动父流程,因此没有要终止的树。
: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"