我将从警告开始:不要创建将在IE中加载的.Net组件。问自己一个问题“如果另一个应用程序做同样的事情会发生什么,它会使用不同版本的CLR?”。 IE不保证加载所需的不同COM组件的任何顺序,因此无法保证在IE调用您的过程中将加载您的CLR版本。
现在解决你的问题了。您的方案存在几个问题:
- .Net不支持本机创建进程外COM组件。是的,可以通过做一堆黑客和手动注册来创建一个;然而,这不是一项简单的任务,需要深入了解COM的工作原理;
- 考虑到上述情况,您的选择实际上是创建一个.Net DLL并使用ComVisible属性来公开COM所需的类。正如您所提到的,您需要使用
RegAsm.exe
进行注册,以便IE能够使用它;
- 由于您希望下载管理器的主要功能位于独立的可执行文件中,因此您必须使用.Net支持的跨进程通信机制。 .Net Remoting可能是实现它的最简单方法,并且应该在很大程度上满足您的要求。另一种方法是在进程中实现下载功能。然而,除了考虑你现在可以轻易地管理IE进程,如果你不小心听它的退出通知(这需要更多的工作本身),还有整个enchilada与IE7 +保护模式,严重限制您的进程内代码可以执行的操作(有限的文件访问,注册表访问,Windows API和其他限制);
- IE8和IE9流程模型存在某些并发症。除了顶级框架进程外,IE8 / 9还创建了一个进程池,并将选项卡负载平衡到这些进程中。我不知道哪个进程会尝试创建你的COM组件,并且每个进程或每个进程或整个IE会话(跨越多个进程)将会是一个进程,所以你必须准备好你可能有多个并发运行的多个进程中的实例。如果是这种情况,您将必须弄清楚如何确保进程内COM组件和可执行文件之间的通信不是一次一个实例序列化,或者您可能会影响用户的浏览体验。 (一个简单的场景是具有多个下载链接的页面,用户右键单击每个链接并选择
Open in new tab
,从而一次在多个选项卡中启动多个下载);
- 即使每个IE会话有一个实例,出于安全原因,提升的IE实例也会在常规用户IE实例的单独会话中运行。有一个有趣的复杂因素是,在升级的IE会话中,来自进程内COM组件的.Net Remoting调用将导致启动的第二个副本也被提升。因此,您的下载管理器必须准备好可能有两个进程访问同一个下载队列;
- 从IE7开始,IE保护模式(默认)将拦截任何导致启动新进程并向用户显示对话框的调用。避免这种情况的唯一方法是为您的进程注册一个静默的IE提升策略。提升策略在
HKEY_LOCAL_MACHINE
中注册,这意味着您需要安装程序,或者至少是一个简单的脚本供用户以管理员身份运行;
- 即使您决定采用提升策略并忍受此对话框的错误体验,要使用IE注册下载管理器,您仍然必须写入HKEY_LOCAL_MACHINE注册表配置单元,否则IE将不会知道它和不会用它。换句话说,您仍然需要某种安装程序或部署脚本;
- IE在测量在UI线程上运行的代码的性能以及在退出进程时终止后台线程方面非常积极。因此,无论您在进程内组件中具有哪些功能,您都必须在UI线程上尽可能快地进行平衡(这意味着更少的工作或者您将影响用户体验)并在后台线程上进行工作(意思是准备好你可能会在没有任何通知的情况下被杀死);
我认为这份清单涵盖了您必须解决的主要问题。您将遇到的最大问题是,在MSDN上没有详细记录IE流程模型的许多细节,并且几乎没有在托管代码中实现此方案的示例(存在的那些,大多数都是旧的,不是更新为IE8 / IE9,有些甚至无法在IE7中工作。