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