web-dev-qa-db-ja.com

WshShell.AppActivateが単純なVBSスクリプトで機能しないようです

合計vbsスクリプトnewbはこちら。開いている特定のウィンドウ、つまりHostsManというプログラムを自動的に閉じることを試みています。これはWindows 8.1 Pro 64ビット上にあり、私のスクリプトは現在次のようになります。

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

2行目は機能していないようです。 3行目はWindowsのシャットダウンメニューをアクティブにするため、機能することはわかっています。足りないものはありますか?

更新/詳細:手動でalt-F4を入力するとそれが閉じられるので、これが機能するはずです。また、このスクリプトを他の開いているウィンドウでテストしたところ、問題なく閉じました。さらに、HostsManは管理者権限で開かれているので、スクリプトを最高の権限を持つタスクセットとして実行して、それが可能かどうかを確認しましたが、それでも実行できませんでした。ただし、これは、管理者権限で実行されている他の開いているウィンドウでは機能します。イライラする!

11
user3550756

私も試してみましたが、うまくいきませんでした。ウィンドウクラスについて何かがあるに違いありません。おそらく、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
11
Bond

AppActivateの問題を解決するには、ループとif条件ステートメントを使用して、アクティブなウィンドウがターゲットウィンドウであるかどうかを確認する必要があります。これは、ターゲットウィンドウの選択を解除したり、システムが選択を解除したりするためです。 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
hollopost

ここで重要なのは、「ru​​n」コマンドの後、「appactivate」コマンドの前に少し一時停止して、アプリケーションがプロセスリストに表示されるようにすることです。

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

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
0
Thierry Dalon
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
0
hollopost