windows WshShell.AppActivate 在简单的 vbs 脚本中似乎不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23165377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 11:31:49  来源:igfitidea点击:

WshShell.AppActivate doesn't seem to work in simple vbs script

windowsvbscript

提问by user3550756

total vbs scripting newb here. I'm trying to automate closing a certain open window, namely a program called HostsMan. This is on Windows 8.1 Pro 64 bit, and this is what my script currently looks like:

总 vbs 脚本 newb 在这里。我正在尝试自动关闭某个打开的窗口,即一个名为 HostsMan 的程序。这是在 Windows 8.1 Pro 64 位上,这就是我的脚本目前的样子:

Set WshShell = CreateObject("WScript.Shell")
WshShell.AppActivate "HostsMan"
WshShell.SendKeys "%{F4}"

The second line doesn't seem to work. I know line 3 works because it activates the Windows shutdown menu. Is there something I'm missing?

第二行似乎不起作用。我知道第 3 行有效,因为它激活了 Windows 关机菜单。有什么我想念的吗?

Update/more info: Manually entering alt-F4 does close it, so I know this should work. I also tested this script with other open windows and they close just fine. Additionally, HostsMan is opened with Admin privileges, so I tried running the script as a task set with highest privileges to see if that would do it, and still no go. But that does work with other open windows running with Admin privileges. Frustrating!

更新/更多信息:手动输入 alt-F4 会关闭它,所以我知道这应该有效。我还用其他打开的窗口测试了这个脚本,它们关闭得很好。此外,HostsMan 以管理员权限打开,因此我尝试将脚本作为具有最高权限的任务集运行,以查看是否可以执行此操作,但仍然没有成功。但这确实适用于以管理员权限运行的其他打开的窗口。令人沮丧!

回答by Bond

I've tried it, too, and couldn't get it to work. There must be something about the window class, perhaps, where AppActivatedoesn't see it as a top-level window?

我也试过了,还是不行。一定有关于窗口类的东西,也许,哪里AppActivate不把它看作是一个顶级窗口?

In any event, AppActivatealso lets you pass the process ID instead of the window title. When I installed HostsMan, the process name was hm.exe, so I'll use that in my example below.

在任何情况下,AppActivate还允许您传递进程 ID 而不是窗口标题。当我安装 HostsMan 时,进程名称是hm.exe,所以我将在下面的示例中使用它。

Set Processes = GetObject("winmgmts:").InstancesOf("Win32_Process")

For Each Process In Processes
    If StrComp(Process.Name, "hm.exe", vbTextCompare) = 0 Then

        ' Activate the window using its process ID...
        With CreateObject("WScript.Shell")
            .AppActivate Process.ProcessId
            .SendKeys "%{F4}"
        End With

        ' We found our process. No more iteration required...
        Exit For

    End If
Next

回答by hollopost

To solve the problem of AppActivateyou have to use loop and if condition statement to check if the active windows is the target windows or not because sometime you deselect or the system deselect the target windows before execute the sendkeys directly so you got error.

要解决AppActivate您必须使用循环和 if 条件语句来检查活动窗口是否为目标窗口的问题,因为有时您在直接执行发送键之前取消选择或系统取消选择目标窗口,因此您会出错。

I create this tight strict way

我创造了这种严格的方式

Set WshShell = CreateObject("WScript.Shell")
    for i=0 to 300 ' this loop will continue about 30 sec if this not enough increase this number
        Rtn=WshShell.AppActivate("HostsMan") ' HostMan have to be the windows title of application or its process ID
        If Rtn = True Then 
            WshShell.SendKeys "%{F4}"    ' send key to click ALT+F4 to close 
            wscript.sleep 100        ' stop execute next line until finish close app
            Rtn=WshShell.AppActivate("HostsMan") 
             If Rtn=False Then ' using nested If to sure of selected windows is false because its close 
               Exit For      ' exit for loop directly and execute what after for next
             End If 
        End If
        wscript.sleep 100
    Next

回答by Jim

The key here is to put a small pause after the 'run' command but before the 'appactivate' command so the application shows up in the process list.

这里的关键是在“运行”命令之后但在“appactivate”命令之前暂停一小段时间,以便应用程序显示在进程列表中。

     WshShell.Run "calc"
     WScript.Sleep 100
     WshShell.AppActivate "Calculator"

回答by hollopost

Dim sh : Set sh =CreateObject("Wscript.Shell")
sh.Exec "calc.exe"
Wscript.Sleep 1000
sh.Exec "taskkill /f /FI ""WINDOWTITLE  eq ""calc*"""

OR

或者

sh.Run "taskkill /f /im calc.exe",0,False

回答by Thierry Dalon

Alternative solution using WMIService (no loop through all processes required):

使用 WMIService 的替代解决方案(不需要循环遍历所有进程):

Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * from Win32_Process WHERE Name = '" & ProcessName & "'") 

If colItems.Count = 0 Then
    WScript.Echo "Process not found"
    Wscript.Quit
End If

For Each objProcess in colItems
    WshShell.AppActivate(objProcess.ProcessId)
    Exit For
Next