AxWebBrowser 实现的多进程浏览器
Posted 皮特胖胖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 也为空。
于是暂时以失败告终。
如果谁能解决,欢迎留言分享!
以上是关于AxWebBrowser 实现的多进程浏览器 的主要内容,如果未能解决你的问题,请参考以下文章