WshShell.AppActivate 似乎无法在简单的 vbs 脚本中工作

问题描述 投票:0回答:5

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

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

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

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

windows vbscript
5个回答
13
投票

我也试过了,但没能成功。肯定有一些关于窗口类的东西,也许,

AppActivate
不认为它是一个顶级窗口?

无论如何,

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

1
投票

使用 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

1
投票

这里的关键是在“run”命令之后、“appactivate”命令之前放置一个小暂停,以便应用程序显示在进程列表中。

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

1
投票

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

我以严格的方式创建这个:

Set WshShell = CreateObject("WScript.Shell")
    for i=0 to 300 ' This loop will continue about 30 seconds 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 executing the next line until finishing closing the application
            Rtn=WshShell.AppActivate("HostsMan")
             If Rtn=False Then ' Using a nested If to be sure of selected windows is false because it's close
               Exit For      ' Exit for loop directly and execute what after for next
             End If
        End If
        wscript.sleep 100
    Next

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

sh.Run "taskkill /f /im calc.exe",0,False
© www.soinside.com 2019 - 2024. All rights reserved.