从强制IE会话关闭应用程序

时间:2009-06-06 16:05:38

标签: c# internet-explorer dispose

我的问题是:“这可以做得更好吗?”如果是的话,怎么样?有什么想法吗?

我们需要在“看不见的”C#.NET 3.5应用程序中启动一个强制IE会话,并在处理完某个请求后退出IE会话和“父”应用程序。

在过去一周左右的时间里,我一直在解决这个问题......今天早上我终于达到了我认为的强大解决方案;但我有点像C#noob(虽然我已经是一名专业的程序员已经10年了),所以我正在寻求第二或第三意见;以及任何其他选项,批评,建议或评论......特别是:SHDocVw仍然是创建“俘虏但未嵌入”的Internet Explorer会话的首选方法吗?

在我看到的情况下,棘手的一点是处理非托管InternetExplorerApplication COM对象,所以我把它包装在一个名为IDisposable的{​​{1}}类

我的基本方法是:

  1. Application.Run MyApp,它是一个ApplicationContext,并且是IQuitable。
    • 我认为需要一个应用程序来保持程序在等待IE请求时保持打开状态?
    • 我想也许一个(非守护进程)监听器循环线程也可以工作?
  2. MyApp的构造函数创建一个新的 InternetExporer 对象传递(IQuitable)this
  3. InternetExplorer的构造函数启动一个新的IE会话,并将其导航到一个URL。
  4. 当请求某个网址时, InternetExporer 会回拨“父母”退出方法。
  5. 背景:

    真实的故事是:我正在为MapInfo(A GIS客户端)编写插件。该插件劫持了从IE到服务器的“开始提取”HTTP请求,稍微修改了URL并在其中发送了HTTPRequest。我们将respose XML解析为MIF files [PDF 196K],然后我们在MapInfo中导入并打开它。然后我们退出IE会话,并关闭“插件”应用程序。

    SSCCE

    InternetExporer

2 个答案:

答案 0 :(得分:1)

我有理由相信System.Windows.Forms.WebBrowser实际上是在内部使用IE Trident浏览器控件。除非您使用的是C#1.x,否则不必进行COM互操作。

答案 1 :(得分:1)

它的长短似乎(我仍然不是专家,无论想象力如何)SHDocVw.dll仍然是启动“俘虏”Internet Explorer会话的首选方法(如同在您的应用程序中嵌入浏览器。)

我之前发布的代码不是最佳解决方案,恕我直言。在最终版本中:

  • IQuitable 是历史
  • MyApp InternetExplorer 类都实现 IDisposable
  • 如果* _isDisposed *为true,则只返回 Dispose 方法。

以下编码包括一些伪代码,为简洁起见:

  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的“俘虏过程”......它是远程控制的东西。令人困惑,但它确实有效...所以当我在这里的时候,我用我最近的学习更新了我的“自我回答”。