Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4553468
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 21, 20262026-05-21T16:57:03+00:00 2026-05-21T16:57:03+00:00

My question is: Can this be done better? and if so, how? Any ideas?

  • 0

My question is: “Can this be done better?” and if so, how? Any ideas?

We need to start a captive IE session from within an “invisible” C# .NET 3.5 application, and quit both the IE session and the “parent” application after processing a certain request.

I’ve been mucking around with this problem for the last week or so… and this morning I’ve finally reached what I think is a robust solution; but I’m a bit of a C# noob (though I’ve been a professional programmer for 10 years), so I’m seeking a second or third opinion; and any other options, critiques, suggestions, or comments… Especially: is SHDocVw still the preferred method of creating a “captive but not imbedded” Internet Explorer session?

As I see things, the tricky bit is disposing of the unmanaged InternetExplorerApplication COM object, so I’ve wrapped it in an IDisposable class called InternetExplorer

My basic approach is:

  1. Application.Run MyApp, which is-a ApplicationContext, and is IQuitable.
    • I think an app is needed to keep the program open whilste we wait for the IE request?
    • I guess maybe a (non-daemon) listener-loop thread might also work?
  2. MyApp’s constructor creates a new InternetExporer object passing (IQuitable)this
  3. InternetExporer‘s constructor starts a new IE session, and navigates it to a URL.
  4. When a certain URL is requested InternetExporer calls-back the “parents” Quit method.

Background:

The real story is: I’m writing a plugin for MapInfo (A GIS Client). The plugin hijacks the “Start Extraction” HTTP request from IE to the server, modifies the URL slightly and sends a HTTPRequest in it’s place. We parse the respose XML into MIF files [PDF 196K], which we then import and open in MapInfo. Then we quit the IE session, and close the “plugin” application.

SSCCE

using System;
using System.Windows.Forms;

// IE COM interface
// reference ~ C:\Windows\System32\SHDocVw.dll 
using SHDocVw; 

namespace QuitAppFromCaptiveIE
{
    static class Program {
        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MyApp());
        }
    }

    interface IQuitable {
        void Quit();
    }

    public class MyApp : ApplicationContext, IQuitable {
        private InternetExplorer ie = null; 

        public MyApp() {
            // create a new Internet Explorer COM component - starts IE application.
            this.ie = new InternetExplorer(this);
            this.ie.Open("www.microsoft.com");
        }

        #region IQuitable Members

        public void Quit() {
            if (ie != null) {
                ie.Dispose();
                ie = null;
            }
            Application.Exit();
        }

        #endregion
    }

    class InternetExplorer : IDisposable, IQuitable
    {
        // allows us to end the parent application when IE is closed.
        private IQuitable parent;
        private bool _parentIsQuited = false;
        private bool _ieIsQuited = false;

        private SHDocVw.InternetExplorer ie; // Old (VB4 era) IE COM component

        public InternetExplorer(IQuitable parent) {
            // lock-onto the parent app to quit it when IE is closed.
            this.parent = parent;
            // create a new Internet Explorer COM component - starts IE application.
            this.ie = new SHDocVw.InternetExplorerClass();
            // hook-up our navigate-event interceptor
            ie.BeforeNavigate2 += new DWebBrowserEvents2_BeforeNavigate2EventHandler(ie_BeforeNavigate2);
        }

        public void Open(string url) {
            object o = null;
            // make the captive IE session navigate to the given URL.
            ie.Navigate(url, ref o, ref o, ref o, ref o);
            // now make the ie window visible
            ie.Visible = true;
        }

        // this callback event handler is invoked prior to the captive IE 
        // session navigating (opening) a URL. Navigate-TWO handles both
        // external (normal) and internal (AJAX) requests. 
        // For example: You could create a history-log file of every page
        // visited by each captive session.
        // Being fired BEFORE the actual navigation allows you to hijack
        // (ie intercept) requests to certain URLs; in this case a request
        // to http://support.microsoft.com/ terminates the Browser session
        // and this program!
        void ie_BeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel) {
            if (URL.Equals("http://support.microsoft.com/")) {
                this.Quit();
            }
        }

        #region IDisposable Members

        public void Dispose() {
            quitIE();
        }

        #endregion

        private void quitIE() {
            // close my unmanaged COM object
            if (ie != null && !_ieIsQuited) {
                _ieIsQuited = true;
                ie.Quit();
                ie = null;
            }
        }

        #region IQuitable Members

        public void Quit() {
            // close my unmanaged COM object
            quitIE();
            // quit the parent app as well.
            if (parent != null && !_parentIsQuited) {
                _parentIsQuited = true;
                parent.Quit();
                parent = null;
            }
        }

        #endregion
    }

}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-21T16:57:04+00:00Added an answer on May 21, 2026 at 4:57 pm

    The long and the short of it appears to be (I’m still NOT an expert, by any stretch of the imagination) that SHDocVw.dll is still the preferred method for launching a “captive” Internet Explorer session (as apposed to embedding a browser in your application).

    The code I posted previously isn’t the best solution, IMHO. In the final version:

    • IQuitable is history
    • Both MyApp and InternetExplorer classes implement IDisposable
    • Both Dispose methods just return if *_isDisposed* is true.

    The following coded includes some pseudocode, for brevity:

      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!
          }
        }
      }
    

    To quit the application from the IE class you just call it’s local Dispose method, which calls MyApps Dispose, which calls IE’s Dispose again but isDisposed is true so it just returns. Then we call Application.ExitThread() and fall out of MyApp’s Dispose… and then we fall out of IE’s Dispose method, and the event-system stops; and the application terminates nicely. Finally!

    NOTE ON EDIT: I’ve just reused this approach with a Robo framework process, which is as a “captive process” of MyApp… the thing it’s remote-controling. Convoluted, but it works… So I update my “self answer” with my latest learnings while I was here.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Simple question. Just wondering if this can be done without me having to enforce
I have not been able to find any definitive answers to this question: Can
This is an interview question, the interview has been done. What things can make
I know this question can be answered by searching in google. But I have
I am using the jQuery-File-Upload widget (although I believe this question can generalize to
I asked a question about different testing frameworks yesterday. This question can be found
I am using the SQL Server PHP Driver, I think this question can be
<hyperbole> Whoever answers this question can claim credit for solving the world's most challenging
I apologize before hand if this is an obvious question: can Apache 2.0 +
You can read this question where I ask about the best architecture for a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.