如何连接到正在运行的 Internet Explorer 实例

警告

已停用、不受支持的 Internet Explorer 11 桌面应用程序在某些版本的 Windows 10 上已通过 Microsoft Edge 更新永久禁用。 有关详细信息,请参阅 Internet Explorer 11 桌面应用停用常见问题解答

可以使用 SHDocVw.ShellWindows 集合连接到正在运行的 Internet Explorer 实例。

原始产品版本: Ie
原始 KB 编号: 176792

更多信息

通常,应用程序使用 表连接到另一个应用程序的正在运行的 Running Object 实例。 由于 Internet Explorer 不会在运行的对象表中注册自身,因此需要另一种方法。

Internet 客户端 SDK 中介绍了 ShellWindows 集合,如下所示:

ShellWindows 对象表示属于 shell 的打开窗口的集合。 事实上,此集合包含对 Internet Explorer 以及属于 shell 的其他窗口(如 Windows 资源管理器)的引用。

以下 Visual Basic 代码获取对 ShellWindows 集合的引用。 枚举集合,并将每个对象的 LocationName 添加到列表框中。 如果与对象关联的文档的类型为 HTMLDocument (网页) ,则页面的标题将添加到另一个列表框中。

若要运行以下代码,需要向 Visual Basic 项目添加对 Microsoft Internet 控件 (Shdocvw.dll) 和 Microsoft HTML 对象库 (Mshtml.dll) 的引用:

Dim SWs As New SHDocVw.ShellWindows
Dim IE As SHDocVw.InternetExplorer

Private Sub Form_Load()
    Dim Doc
    List1.Clear
    List2.Clear

    Text1.Text = SWs.count

    For Each IE In SWs
        List1.AddItem IE.LocationName

        Set Doc = IE.Document
        If TypeOf Doc Is HTMLDocument Then
            'if this is an HTML page, display the title
            'may or may not be the same as LocationName
            List2.AddItem Doc.Title
        End If
    Next
End Sub

在 C++ 中,可以采用大致相同的方式完成连接。 为了简洁起见,此处使用 Visual C++ Native COM 支持。

向项目添加对 Shdocvw.dllMshtml.dll 的引用:

#import <mshtml.dll> // Internet Explorer 4.0x
#import <mshtml.tlb> // Internet Explorer 5
#import <shdocvw.dll>

在视图类中声明 IShellWindows 指针的实例:

SHDocVw::IShellWindowsPtr m_spSHWinds;

在视图的构造函数中创建 ShellWindows 对象的实例:

m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows));

在视图的 OnInitialUpdate 函数中使用 ShellWindows 对象:

void CConnectIEView::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();

    ASSERT(m_spSHWinds != NULL);

    CString strCount;
    long nCount = m_spSHWinds->GetCount();

    strCount.Format("%i", nCount);
    m_strWinCount = strCount;

    UpdateData(FALSE);

    IDispatchPtr spDisp;
    for (long i = 0; i < nCount; i++)
    {
        _variant_t va(i, VT_I4);
        spDisp = m_spSHWinds->Item(va);

        SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
        if (spBrowser != NULL)
        {
            m_ctlListLoc.AddString(spBrowser->GetLocationName());

            MSHTML::IHTMLDocument2Ptr spDoc(spBrowser->GetDocument());
            if (spDoc != NULL)
            {
                m_ctlListTitle.AddString(spDoc->Gettitle());
            }
        }
    }
}

如果未安装 Shell 集成,或者在 Internet Explorer 中选择了“浏览”, 则连接到 Internet Explorer 正在运行的实例的先前方法不起作用。

如果不能控制这些因素,仍有一种可能的方法可能有效。 可以编写浏览器帮助程序对象,以在运行的对象表中注册 Internet Explorer, (ROT) 。 此处有许多可能实现,具体取决于应用程序如何确定要连接的 Internet Explorer 实例。 只有一种可能的解决方案:浏览器帮助程序对象(有权访问启动它的 Explorer 实例的对象模型)将确定这是否是应在运行的对象表中注册的浏览器实例。

使用者感兴趣的接口可以使用 RegisterActiveObject 函数和使用者将识别的虚拟 CLSID 在 ROT 中注册。 允许在 ROT 中注册资源管理器的多个实例的另一种解决方案是,让浏览器帮助程序对象基于每个 Internet Explorer 实例唯一的 GUID 和数据片段组成项名字对象。 名字对象将使用 方法在 ROT IRunningObjectTable::Register 中注册。 同样,使用者必须知道如何识别此名字对象。

References

有关 Windows Shell SDK 的详细信息,请参阅 Windows Shell

有关特定于 Internet Explorer 的开发人员的详细信息,请参阅 适用于开发人员的 Internet Explorer