这里是 vbs 脚本新手。我正在尝试自动关闭某个打开的窗口,即一个名为 HostsMan 的程序。这是在 Windows 8.1 Pro 64 位上,这就是我的脚本当前的样子:
Set WshShell = CreateObject("WScript.Shell")
WshShell.AppActivate "HostsMan"
WshShell.SendKeys "%{F4}"
第二行似乎不起作用。我知道第 3 行有效,因为它激活了 Windows 关闭菜单。我有什么遗漏的吗?
更新/更多信息:手动输入 alt-F4 确实会关闭它,所以我知道这应该可行。我还用其他打开的窗口测试了这个脚本,它们关闭得很好。此外,HostsMan 是使用管理员权限打开的,因此我尝试将脚本作为具有最高权限的任务集运行,看看是否可以做到这一点,但仍然不行。但这确实适用于以管理员权限运行的其他打开的窗口。令人沮丧!
我也试过了,但没能成功。肯定有一些关于窗口类的东西,也许,
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
使用 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
这里的关键是在“run”命令之后、“appactivate”命令之前放置一个小暂停,以便应用程序显示在进程列表中。
WshShell.Run "calc"
WScript.Sleep 100
WshShell.AppActivate "Calculator"
要解决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
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