如何在Windows中启动另一个进程时启动进程?

时间:2015-12-01 11:41:54

标签: windows batch-file vbscript startup

我试图创建一种检查某个程序是否正在运行的方法 - 如果是,则启动另一个程序。

这是我在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上运行。

1 个答案:

答案 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。

进一步阅读: