WshShell.AppActivate, похоже, не работает в простых vbs script
Всего vbs скриптов newb здесь. Я пытаюсь автоматизировать закрытие определенного открытого окна, а именно программу под названием HostsMan. Это на 64-разрядной версии Windows 8.1 Pro, и именно это выглядит в настоящее время мой script:
Set WshShell = CreateObject("WScript.Shell")
WshShell.AppActivate "HostsMan"
WshShell.SendKeys "%{F4}"
Вторая строка, похоже, не работает. Я знаю, что строка 3 работает, потому что она активирует меню выключения Windows. Что-то мне не хватает?
Обновление/дополнительная информация: Ввод вручную alt-F4 закрывает его, поэтому я знаю, что это должно работать. Я также проверил этот script с другими открытыми окнами, и они закрылись просто отлично. Кроме того, HostsMan открывается с правами администратора, поэтому я попробовал запустить script как набор задач с наивысшими привилегиями, чтобы увидеть, будет ли это делать, и все равно не идти. Но это работает с другими открытыми окнами с правами администратора. Срыв!
Ответы
Ответ 1
Я тоже пробовал и не мог заставить его работать. Возможно, что-то должно быть в классе окон, где AppActivate
не видит его как окно верхнего уровня?
В любом случае AppActivate
также позволяет передавать идентификатор процесса вместо заголовка окна. Когда я установил 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
Ответ 2
Чтобы решить проблему AppActivate
, вы должны использовать цикл и оператор условия, чтобы проверить, являются ли активные окна целевыми окнами или нет, потому что когда-нибудь вы отменяете выбор или система отменяет выбор целевых окон перед выполнением sendkeys напрямую, чтобы вы получили ошибку.
Я создаю этот жесткий строгий способ
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
Ответ 3
Ключ здесь заключается в том, чтобы поставить небольшую паузу после команды "run", но перед командой "appactivate", чтобы приложение отображалось в списке процессов.
WshShell.Run "calc"
WScript.Sleep 100
WshShell.AppActivate "Calculator"
Ответ 4
Альтернативное решение с использованием 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
Ответ 5
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