zoukankan      html  css  js  c++  java
  • AxWebBrowser 实现的多进程浏览器 (一)

    我们使用 C#/VB.NET 进行 Trident 内核浏览器编程,大多都是单进程的,当打开的页面较多时比较容易出现卡死等情况。

    单进程浏览器简单示例:

    Public Class formBrowser
        Public WithEvents awb As New AxSHDocVw.AxWebBrowser
        Public isFirst As Boolean = True
    
        Private Sub formBrowser_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            awb.Dock = DockStyle.Fill
            Me.Controls.Add(awb)
            awb.Silent = True
            If isFirst Then awb.Navigate("http://www.geeuo.com")
        End Sub
    
        Private Sub awb_NewWindow3(sender As Object, e As AxSHDocVw.DWebBrowserEvents2_NewWindow3Event) Handles awb.NewWindow3
            Dim newForm As New formBrowser
            newForm.isFirst = False
            newForm.Show()
            e.ppDisp = newForm.awb.Application
        End Sub
    End Class
    

      

    从上面的代码可以看出,实现“多进程”的核心,可能就在 AxWebBrowser.NewWindow3 事件当中,在需要打开新的浏览器窗口时,我们只需要创建新的进程,并让新的网址页面在新的进程中打开,应该就可以了。

    那么如何实现跨进程传递 AxWebBrowser.Application 对象呢?跨进程传递com对象貌似涉及到C++指针部分内容,实在太高深。

    谷歌了一番发现可以通过“Internet Explorer_Server”句柄获取其所在的IWebBrowser2接口对象,而“IWebBrowser2”接口同样存在“Application”属性。

    但是貌似 AxWebBrowser 并未实现 IWebBrowser2 接口?不管了,试试看行不行再说。

    Declare Function ObjectFromLresult Lib "OLEACC.DLL" (ByVal lResult As Int32, ByRef riid As System.Guid, ByVal wParam As Int32, ByRef ppvObject As mshtml.IHTMLDocument) As Int32
    
    <System.Runtime.InteropServices.DllImport("User32.dll")>
    Public Shared Function RegisterWindowMessage(message As String) As Integer
    End Function
    
    <System.Runtime.InteropServices.DllImport("User32.dll")>
    Public Shared Function SendMessageTimeout(hWnd As IntPtr, uMsg As Integer, wParam As IntPtr, lParam As IntPtr, fuFlags As Integer, uTimeout As Integer, ByRef lpdwResult As UIntPtr) As Integer
    End Function
    
    <System.Runtime.InteropServices.ComImport, System.Runtime.InteropServices.Guid("6d5140c1-7436-11ce-8034-00aa006009fa"), System.Runtime.InteropServices.InterfaceType(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)>
    Public Interface IServiceProvider
        Sub QueryService(ByRef guidService As Guid, ByRef riid As Guid, <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Interface)> ByRef ppvObject As Object)
    End Interface
    
    <System.Runtime.InteropServices.DllImport("kernel32.dll")>
    Public Shared Function LoadLibrary(lpLibFileName As String) As Integer
    End Function
    
    
    Public Shared Function GetIWebBrowser2(hwndInterneExplorer_Server As IntPtr) As SHDocVw.IWebBrowser2
        Dim IID_IWebBrowser2 As Guid = GetType(SHDocVw.IWebBrowser2).GUID
        Dim IID_IHTMLDocument2 As Guid = GetType(mshtml.IHTMLDocument2).GUID
        Dim SID_SWebBrowserApp As Guid = GetType(SHDocVw.IWebBrowserApp).GUID
        Dim doc2 As mshtml.IHTMLDocument2, web2 As SHDocVw.IWebBrowser2, tmpObj As Object
        doc2 = Nothing : web2 = Nothing : tmpObj = Nothing
        Try
            LoadLibrary("OLEACC.DLL")
            Dim nMsg As Integer = RegisterWindowMessage("WM_HTML_GETOBJECT")
            Dim lRes As UIntPtr = UIntPtr.Zero
            SendMessageTimeout(hwndInterneExplorer_Server, nMsg, New IntPtr(), New IntPtr(), &H2, 1000, lRes)  ' SMTO_ABORTIFHUNG = &H2
            If lRes.ToUInt32 <> 0 Then
                ObjectFromLresult(CInt(lRes.ToUInt32()), IID_IHTMLDocument2, 0, doc2)
                If doc2 IsNot Nothing Then
                    System.Runtime.InteropServices.Marshal.GetIUnknownForObject(doc2)
                    TryCast(doc2, IServiceProvider).QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, tmpObj)
                    web2 = TryCast(tmpObj, SHDocVw.IWebBrowser2)
                End If
            End If
        Catch
        End Try
        Return web2
    End Function
    

      

    测试了一下,可以实现在新进程中打开新的页面,然而新页面并未与之前的页面共享 session。而且新页面的 referrer 也为空。

    于是暂时以失败告终。

    如果谁能解决,欢迎留言分享!

  • 相关阅读:
    VUE常用传值方式、父传子、子传父、非父子组件传值
    ios10中禁止用户缩放页面
    TCP MSS
    C++11 之 override
    unordered_set
    c++Lambda
    QUIC实现代码分析
    C++11新特性之十:enable_shared_from_this
    c++11 atomic
    How to Write a QUIC Endpoint Program
  • 原文地址:https://www.cnblogs.com/hironpan/p/7634823.html
Copyright © 2011-2022 走看看