我的问题是:“这可以做得更好吗?”如果是的话,怎么样?有什么想法吗?
我们需要在“看不见的”C#.NET 3.5应用程序中启动一个强制IE会话,并在处理完某个请求后退出IE会话和“父”应用程序。
在过去一周左右的时间里,我一直在解决这个问题......今天早上我终于达到了我认为的强大解决方案;但我有点像C#noob(虽然我已经是一名专业的程序员已经10年了),所以我正在寻求第二或第三意见;以及任何其他选项,批评,建议或评论......特别是:SHDocVw仍然是创建“俘虏但未嵌入”的Internet Explorer会话的首选方法吗?
在我看到的情况下,棘手的一点是处理非托管InternetExplorerApplication
COM对象,所以我把它包装在一个名为IDisposable
的{{1}}类
我的基本方法是:
InternetExplorer
的构造函数启动一个新的IE会话,并将其导航到一个URL。背景:
真实的故事是:我正在为MapInfo(A GIS客户端)编写插件。该插件劫持了从IE到服务器的“开始提取”HTTP请求,稍微修改了URL并在其中发送了HTTPRequest。我们将respose XML解析为MIF files [PDF 196K],然后我们在MapInfo中导入并打开它。然后我们退出IE会话,并关闭“插件”应用程序。
SSCCE
InternetExporer
答案 0 :(得分:1)
我有理由相信System.Windows.Forms.WebBrowser实际上是在内部使用IE Trident浏览器控件。除非您使用的是C#1.x,否则不必进行COM互操作。
答案 1 :(得分:1)
它的长短似乎(我仍然不是专家,无论想象力如何)SHDocVw.dll仍然是启动“俘虏”Internet Explorer会话的首选方法(如同在您的应用程序中嵌入浏览器。)
我之前发布的代码不是最佳解决方案,恕我直言。在最终版本中:
以下编码包括一些伪代码,为简洁起见:
private volatile bool _isDisposed = false;
/**
* _isDisposed stops the two "partners" in the conversation (us and
* Internet Explorer) from going into "infinite recursion", by calling
* each others Dispose methods within there Dispose methods.
*
* NOTE: I **think** that making _isDisposed volatile deals adequately
* with the inherent race condition, but I'm NOT certain! Comments
* welcome on this one.
*/
public void Dispose() {
if (!_isDisposed) {
_isDisposed = true;
try {
try { release my unmanaged resources } catch { log }
try {
IE calls MyApp.Dispose() here // and FALLOUT on failure
MyApp calls IE.Dispose(); here
} catch {
log
}
} finally {
base.Dispose(); // ALLWAYS dispose base, no matter what!
}
}
}
要从IE类中退出应用程序,您只需调用它的本地Dispose方法,该方法调用MyApps Dispose,它再次调用IE的Dispose,但isDisposed为true,因此它只返回。然后我们调用Application.ExitThread()并从MyApp的Dispose中删除...然后我们脱离了IE的Dispose方法,并且事件系统停止了;并且应用程序很好地终止。终于来了!
注意编辑:我刚刚使用Robo框架流程重用这种方法,这是MyApp的“俘虏过程”......它是远程控制的东西。令人困惑,但它确实有效...所以当我在这里的时候,我用我最近的学习更新了我的“自我回答”。