【问题标题】:appactivate between multiple internet explorer instances多个 Internet Explorer 实例之间的 appactivate
【发布时间】:2014-04-30 19:07:10
【问题描述】:

是否可以使用 wshshell.appactivate 在多个 Internet Explorer 窗口之间切换?

我正在尝试编写一个脚本,它将以 kiosk 模式将 Internet Explorer 的不同实例带到前面。最终目标是让它看起来像是从一个网页转到下一个网页。我尝试使用 wshshell.sendkey,但弹出的打开网页对话框看起来并不流畅。

【问题讨论】:

  • 当然。你的意思是窗口,不是标签,对吧?

标签: internet-explorer batch-file vbscript


【解决方案1】:

我玩了几天。我们可以从 IE 中获取 hwnd,但不能获取 PID。所以我能看到将 HWnd 与 PID 匹配的唯一方法是调用 Win32API 调用。那么如何在 VBS 中做到这一点。

所有计算机都安装了 4 个 VB.NET 编译器。所以我们需要做的就是编写一个包装GetWindowThreadProcessId的com服务器。

在您的脚本中,将以下行写入文本文件。我为此重新使用了不同的脚本,所以方法名称很愚蠢。

Imports System
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Imports System.Net.Mail



Namespace SendMail

    <Guid("85B4AD6D-2E89-4869-9BBC-69E42738FCFC"), _
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
   Public Interface _SendMail
        <DispId(1)> Function Send(ByVal hWnd As Integer) As Integer
    End Interface

    <Guid("C91EDEB2-3756-4893-905B-0E4E2150C7FD"), _
     ClassInterface(ClassInterfaceType.None), _
     ProgId("Scripting.SendMail")> Public Class SendMail
        Implements _SendMail

        Public SendMail()
        Public Declare Auto Function GetWindowThreadProcessId Lib "user32" Alias "GetWindowThreadProcessId" (ByVal hwnd As Integer, ByRef lpdwProcessId As Integer) As Integer

        Public Function Send(HWnd as Integer) As Integer Implements _SendMail.Send
            Dim X as Integer
            Dim M as Integer
    M=1

            X=GetWindowThreadProcessID(HWnd,M)
            msgbox(X & " " & M & " " & HWnd & " " & Err.LastDllError)
            Send = M

        End Function

    End Class

End Namespace

然后编译WSHShell。运行以下命令隐藏修复路径。

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe" /target:library /out:"%userprofile%\desktop\sendmail\sendmail.dll" "%userprofile%\desktop\sendmail\sendmail.cls" /verbose


"C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm" /codebase "%userprofile%\desktop\sendmail\sendmail.dll" /tlb:"%userprofile%\desktop\sendmail\sendmail.tlb" /v

然后在脚本中使用

Set x = CreateObject("Scripting.SendMail")
Msgbox x.Send(&h1a013e)

现在我已经生成了 GUID 用于动态创建 com 对象。因为它们现在是公共代码,所以您(以及任何其他复制此代码的人)必须销毁脚本中的对象。使用 /u 运行 Regasm 命令。或者生成新的 GUID。

【讨论】:

    【解决方案2】:

    您可以枚举所有资源管理器/Internet Explorer 窗口。

    来自帮助

    Windows 方法


    创建并返回一个 ShellWindows 对象。此对象表示属于 Shell 的所有打开窗口的集合。

    语法

    oWindows = Shell.Windows()
    

    返回值

    对 ShellWindows 对象的对象引用。

    例子

    以下示例使用 Windows 检索 ShellWindows 对象并显示它包含的项目数。正确使用 Microsoft JScript、Microsoft Visual Basic Sc​​ripting Edition (VBScript) 和 Visual Basic。 VBScript:

    显示示例

    <script language="VBScript">
        function fnShellWindowsVB()
            dim objShell
            dim objShellWindows
    
            set objShell = CreateObject("Shell.Application")
            set objShellWindows = objShell.Windows
    
            if (not objShellWindows is nothing) then
                alert(objShellWindows.Count)
            end if
    
            set objShellWindows = nothing
            set objShell = nothing
        end function
     </script>
    

    但我不知道这会有什么帮助,除非它们有不同的标题栏文本。 Appactivate 是唯一可用于脚本的 Windows 管理命令。

    appactivate 还返回一个值,说明它是否使窗口处于活动状态。如果您尝试激活活动窗口,则会失败,因为该窗口已经处于活动状态。

    您可以进行进程切换,但通常网页处于同一进程中。 AppActivate 需要一个 PID

    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    
    Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")
    
    For Each objItem in colItems
        msgbox objItem.ProcessID & " " & objItem.Caption
    Next
    

    【讨论】:

    • “如果您尝试激活活动窗口,它会失败,因为该窗口已经处于活动状态。” 我不相信这是真的。它应该返回True,无论窗口在调用之前是否已经处于活动状态。
    • Internet Explorer 确实有唯一的 PID,但无法知道它们在启动时会分配到什么编号。我不知道如何搜索进程并找到 PID 号。
    • @Bond。 PuTTY 或 NetTerm 都是如此。但也许它们不寻常。
    猜你喜欢
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 2014-10-04
    • 2018-10-27
    相关资源
    最近更新 更多