2015-12-01 157 views
1

我想创建一个方法来检查某个程序是否正在运行 - 如果是,请启动另一个程序。如何在Windows中启动另一个进程时启动进程?

这是我在英美烟草

@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使用率(与I5-4670k 20至60%)。

我做错了什么?或者我可以改进代码吗?我正在考虑放慢窗口检查过程的时间(即等待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 

EDIT

这里是钟声和 - 口哨使用反应以在Windows一个过程的开始和终止的复杂的方式VBScript中。

它可以与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。

延伸阅读:

+1

正如我之前说过的,我的编码知识非常低(我基本刚刚开始),而且我试图不只是复制其他人的粘贴代码,而是学习一些东西。 这就是说,这是我发现在后台运行bat文件(而不是打开CMD)的唯一方式是否有更好的方法呢? – XenSide

+0

它工作完美无瑕,我只需在开始和目录之间添加双“”,我甚至将超时时间缩短到1.5,性能非常完美,爱你的伴侣。 你唯一能做的更好的事情就是向像我这样的不喜欢的人解释变化。 谢谢。 – XenSide

+0

我不确定那个超时支持spit-seconds。我也在研究用另一种技术来扩展这个答案,可能会让我花一点时间,坚持下去。 – Tomalak

相关问题