使用Microsoft AddIn Framework隔离浏览器控件

在开发复杂的应用程序时,经常需要在应用程序中嵌入浏览器控件,以便用户能够浏览网页。然而,浏览器控件可能会遇到内存泄漏、错误和异常等问题,这些问题可能会影响整个应用程序的稳定性。为了解决这个问题,可以使用Microsoft AddIn Framework (MAF) 来在独立进程中托管浏览器控件,从而将这些问题隔离开来。本文将详细介绍如何实现这一目标。

Microsoft AddIn Framework 基础

对于不熟悉MAF的初学者,建议先访问MSDN文档,了解Pipeline Development的基本架构。MAF允许开发者创建可在不同进程中运行的插件,这些插件可以与宿主应用程序进行双向通信。

浏览器宿主应用程序

应用程序是一个WPF窗口应用程序,它使用AddIn浏览器控件在单独的进程中导航到指定的URL。以下是应用程序的主要功能:

  • 加载浏览器:在指定的框架中加载浏览器控件。
  • 卸载浏览器:卸载浏览器控件并终止AddIn进程。
  • 导航:导航到指定的URL。
  • 列表框URL:显示从BeforeNavigate事件导航的URL。
  • 从列表导航:选择一个URL并点击以导航到选定的URL。

使用代码

项目包含七个项目,每个项目都引用了Pipeline Architecture中的一个层。以下是每个项目的主要功能:

项目1: AppContracts

定义接口IBrowserAddInContract,该接口派生自IContract,并将其标记为AddInContract。IBrowserAddInContract接口需要在AddIn中实现,以便使用AddIn框架在进程外运行浏览器。该接口有两个方法,一个用于获取句柄,另一个用于导航到指定的URL。

public interface IBrowserAddInContract : IContract { INativeHandleContract GetUI(); void Navigate(string url, string cookie); void BeforeNavigateEventAdd(INavigateEventHandler handler); void BeforeNavigateEventRemove(INavigateEventHandler handler); }

定义两个接口,一个用于处理AddIns在宿主应用程序中引发的事件,另一个用于传递事件参数。

public interface INavigateEventHandler : IContract { bool Handler(INavigateEventArgs args); } public interface INavigateEventArgs : IContract { string url { get; } }

项目2: HostSideAdapter

在这个项目中,引用AppContracts和BrowserHostView项目。实现两个类,一个用于从ContractToHost调用方法,另一个用于HostToContract。

项目3: AddInSideAdapter

在这个项目中,引用AppContracts和BrowserAddInView项目。这个项目中的一个重要任务是处理运行事件的调度器,这在AppDispatcher类中完成。

项目4 & 5: BrowserAddInView 和 BrowserHostView

这两个项目定义了视图类为抽象类。AppContracts中的所有方法都已定义。

[AddInBase] public abstract class BrowserAddIn { public abstract event System.EventHandler Navigating; public abstract FrameworkElement GetUI(); public abstract void Navigate(string url, string cookie); }

项目6: BrowserHostApplication

在这个项目中,引用BrowserHostView。使用LoadAddIn方法中提到的特定类型的AddIn。使用AddInStore静态方法FindAddIns检索机器上特定路径上可用的AddIns。

private void LoadAddIn() { String path = Environment.CurrentDirectory; String[] warnings = AddInStore.Rebuild(path); IList<AddInToken> tokens = AddInStore.FindAddIns( typeof(BrowserHostView.BrowserAddIn), path); addins = new List<BrowserHostView.BrowserAddIn>(); ap = new AddInProcess(); ap.Start(); AddInStore.FindAddIns( typeof(BrowserHostView.BrowserAddIn), PipelineStoreLocation.ApplicationBase); addInInstance = tokens[0].Activate<BrowserHostView.BrowserAddIn>(ap, AddInSecurityLevel.FullTrust); addins.Add(addInInstance); addInIndex = dp.Children.Add(c.GetUI()); addInInstance.Navigating += new EventHandler<BrowserHostView.NavigateEventArgs>(usercontrol_BeforeNavigate); }

要卸载AddIn,移除事件并关闭进程:

private void UnloadAddIn() { addInInstance.Navigating -= usercontrol_BeforeNavigate; dp.Children.RemoveAt(addInIndex); addInInstance = null; ap.Shutdown(); }

项目7: BrowserAddIn

声明一个新类BrowserAddInCode,并将其标记为[System.AddIn.AddIn("BrowserAddIn")]。实现抽象视图类及其方法GetUI、Navigate和NavigatingEventCall。这个类实例化了BrowserControl。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485