我试图创建一种检查某个程序是否正在运行的方法 - 如果是,则启动另一个程序。
这是我在BAT的进展
@ECHO OFF
:LOOP
tasklist /nh /fi "imagename eq steam.exe" | find /i "steam.exe" >nul && START "" "C:\Program Files\TeamSpeak 3 Client\ts3client_win64.exe" || goto :LOOP
我创建了一个基本上在Windows启动时启动BAT的VBS(这只是为了确保批处理文件在没有可见控制台窗口的情况下运行):
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Run chr(34) & "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\if Steam running then TS.bat" & Chr(34), 0
Set WshShell = Nothing
我的问题是这样做,我的CPU使用率非常高(20到60%,I5-4670k)。
我做错了什么吗?或者我可以改进代码吗?我正在考虑减慢窗口检查过程的时间(即等待2秒然后检查),但我对编码很新,我不知道如何这样做。
我知道我的英语并不完美,不好意思。
编辑:如果有帮助,我的电脑在Windows 10上运行。
答案 0 :(得分:3)
我的CPU使用率非常高
您需要让计算机在支票之间休息一下。 timeout
命令中断批处理执行的可配置秒数:
@echo off
setlocal
set "FIND_STEAM=tasklist /nh /fi "imagename eq steam.exe" ^| find /i "steam.exe" ^> NUL"
set "START_TS=start "C:\Program Files\TeamSpeak 3 Client\ts3client_win64.exe""
:LOOP
timeout 5 > NUL
%FIND_STEAM% && %START_TS% || goto LOOP
修改
以下是使用VBScript对Windows中进程的启动和终止作出反应的复杂方法。
它适用于WMI,这是一个功能强大的框架,可以在Windows中执行各种操作。在这里,我们使用它来监听流程创建和流程终止事件。 (听事件比每隔一秒左右轮询所有进程要高效得多):
Option Explicit
Dim WMIService, ProcessNew, ProcessEnd
Dim computer, query, teamspeakPID
' create a WMI service object and ProcessNew / ProcessEnd event sinks
computer = "."
Set WMIService = GetObject("winmgmts:\\" & computer & "\root\CIMV2")
Set ProcessNew = WScript.CreateObject("WbemScripting.SWbemSink", "ProcessNew_")
Set ProcessEnd = WScript.CreateObject("WbemScripting.SWbemSink", "ProcessEnd_")
' we will be waiting for Win32_Process creation events and notify event sink "ProcessNew"
WMIService.ExecNotificationQueryAsync ProcessNew, _
"SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'"
' we will also be waiting for Win32_Process deletion events and notify event sink "ProcessEnd"
WMIService.ExecNotificationQueryAsync ProcessEnd, _
"SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'"
' main loop: nothing to do, we just sit and wait
While True
Wscript.Sleep(500)
Wend
' function that handles "process created" events
Sub ProcessNew_OnObjectReady(latestEvent, asyncContext)
Dim process
If LCase(latestEvent.TargetInstance.Name) = "steam.exe" Then
' start TeamSpeak
Set process = GetObject("winmgmts:Win32_Process")
process.Create "C:\Program Files\TeamSpeak 3 Client\ts3client_win64.exe", null, null, teamspeakPID
End If
End Sub
' function that handles "process ended" events
Sub ProcessEnd_OnObjectReady(latestEvent, asyncContext)
Dim processList, process
If LCase(latestEvent.TargetInstance.Name) = "steam.exe" Then
' kill TeamSpeak (but only the one we started earlier)
Set processList = WMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'ts3client_win64.exe' AND ProcessId = " & teamspeakPID)
For Each process in processList
process.Terminate()
Next
End If
End Sub
作为练习,您可以尝试对其进行扩展,以便它仅在尚未运行时启动TS。
进一步阅读:
Technet" Scripto博士的剧本商店"柱
MSDN