How to detect if an application has stopped responding by using Visual C# (304991)



The information in this article applies to:

  • Microsoft Visual C# .NET (2002)
  • Microsoft Visual C# 2005

This article was previously published under Q304991
For a Microsoft Visual Basic .NET version of this article, see 304990.
This article refers to the following Microsoft .NET Framework Class Library namespaces:
  • SHDocVw
  • System.Diagnostics

IN THIS TASK

SUMMARY

This step-by-step article shows you how to detect whether an automated instance of Internet Explorer has stopped responding (hung) and how to close Internet Explorer.

In some situations, you may want to detect if an application is blocked. For example, when you are automating Microsoft Internet Explorer, you may want to know if Internet Explorer has stopped responding.

Although the code is written for Internet Explorer and Visual C# .NET, you can use this approach for other applications also.

The first three sections in this article outline the three important coding concepts that are necessary to accomplish this task. The fourth section demonstrates how to build the sample application.

back to the top

Start the Application

The sample for this article uses Internet Explorer as the test application. The following code starts Internet Explorer and uses the GetProcessByName method to get a handle to the process.
   Browser = new InternetExplorer();
   Browser.Visible = true;
   Browser.GoHome();
   procs = Process.GetProcessesByName("IEXPLORE");
				
back to the top

Determine If the Application Is Responding

The following code checks the first element in the array procs, which the GetProcessByName method returns, to determine if the process is responding. This article assumes that only one instance of Internet Explorer is running.
    if (Browser!=null)
        if (procs[0].Responding )	
	    MessageBox.Show("IEXPLORE is Responding");
	else
	    MessageBox.Show("IEXPLORE is Not Responding");
    else
	MessageBox.Show("IEXPLORE is Not Running");
				
back to the top

Close the Application

The following code demonstrates how to close the application. If the application is still responsive, you can use the CloseMainWindows method of the Process class to close it. If the application is not responsive, you must call the Kill method. You must use the try-catch block to handle the exception that is thrown if the process does not exist.
    try
        {
        if (procs[0].Responding)
            procs[0].CloseMainWindow();
        else
	    procs[0].Kill();
	}
    catch 
	{
	MessageBox.Show("Could Not Find the IEXPLORE Process");
	}

				
back to the top

Build the Sample Project

About the Sample

The sample project in this article consists of a form with the following three buttons:
  • Start Internet Explorer, which uses Automation to start an instance of Internet Explorer.
  • Check Internet Explorer, which tests to see if the browser is responding.
  • Close Internet Explorer, which closes the browser.
If you want to give this code a thorough test and know of a Web page that will cause the browser to stop responding, you can browse to that page after you open the browser. Then, try to click Check Internet Explorer and Close Internet Explorer. Allow a few moments after you click the buttons; the response is not immediate when the browser is unresponsive. back to the top

Steps to Build the Sample

  1. Start a new C# Windows Application in Visual C# .NET or Visual C# 2005.
  2. In the Solution Explorer window, right-click References, and then click Add Reference.
  3. On the COM tab in the Add Reference dialog box, click Microsoft Internet Controls, and then click Select.
  4. Click OK to close the Add Reference dialog box.NOTE: If you see the following dialog box, click Yes to create the required wrapper:
    Could not find a primary interop assembly for the COM component 'Microsoft Internet Controls'. A primary interop assembly is not registered for this type library. Would you like to have a wrapper generated for you?
    If you do not see this dialog box, you probably have the necessary interop wrapper.

  5. In the Solution Explorer window, right-click Form1.cs, and then click View Code.
  6. Delete all of the code from the Form1.cs code window.
  7. Paste the following code in the Form1.cs code window:
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using SHDocVw;
    using System.Diagnostics;
    namespace appStoppedresponding_cs
    {
      public class Form1 : System.Windows.Forms.Form
      {
        private System.Windows.Forms.Button btnStart;
        private System.Windows.Forms.Button btnCheck;
        private System.Windows.Forms.Button btnClose;
        
        private System.ComponentModel.Container components = null;
    
        private  InternetExplorer Browser;
        protected Process[] procs;
        
        public Form1()
        {
          InitializeComponent();
        }
      
        protected override void Dispose( bool disposing )
        {
          if( disposing )
          {
            if (components != null) 
            {
              components.Dispose();
            }
          }
          base.Dispose( disposing );
        }
    
        #region Windows Form Designer generated code
        
        private void InitializeComponent()
        {
          this.btnCheck = new System.Windows.Forms.Button();
          this.btnStart = new System.Windows.Forms.Button();
          this.btnClose = new System.Windows.Forms.Button();
          this.SuspendLayout();
          // 
          // btnCheck
          // 
          this.btnCheck.Location = new System.Drawing.Point(66, 122);
          this.btnCheck.Name = "btnCheck";
          this.btnCheck.Size = new System.Drawing.Size(152, 23);
          this.btnCheck.TabIndex = 1;
          this.btnCheck.Text = "Check Internet Explorer";
          this.btnCheck.Click += new System.EventHandler(this.btnCheck_Click);
          // 
          // btnStart
          // 
          this.btnStart.Location = new System.Drawing.Point(66, 74);
          this.btnStart.Name = "btnStart";
          this.btnStart.Size = new System.Drawing.Size(152, 23);
          this.btnStart.TabIndex = 0;
          this.btnStart.Text = "Start Internet Explorer";
          this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
          // 
          // btnClose
          // 
          this.btnClose.Location = new System.Drawing.Point(66, 170);
          this.btnClose.Name = "btnClose";
          this.btnClose.Size = new System.Drawing.Size(152, 23);
          this.btnClose.TabIndex = 2;
          this.btnClose.Text = "Close Internet Explorer";
          this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
          // 
          // Form1
          // 
          this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
          this.ClientSize = new System.Drawing.Size(292, 266);
          this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                          this.btnClose,
                                          this.btnCheck,
                                          this.btnStart});
          this.Name = "Form1";
          this.Text = "Form1";
          this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
          this.Load += new System.EventHandler(this.Form1_Load);
          this.ResumeLayout(false);
    
        }
        #endregion
    
        //example code
        /// The main entry point for the application.
        [STAThread]
        static void Main() 
        {
          Application.Run(new Form1());
        }
        
        private void btnStart_Click(object sender, System.EventArgs e)
        {
          Browser = new InternetExplorer();
          Browser.Visible = true;
          Browser.GoHome();
          procs = Process.GetProcessesByName("IEXPLORE");
          //Build event delegate to catch browser close event.
          SHDocVw.DWebBrowserEvents2_OnQuitEventHandler oDelegate = new
            SHDocVw.DWebBrowserEvents2_OnQuitEventHandler(Browser_OnQuit);
               Browser.OnQuit += oDelegate;
        }
    
        private void btnCheck_Click(object sender, System.EventArgs e)
        {
          if (Browser!=null)
          
            if (procs[0].Responding )  
              MessageBox.Show("IEXPLORE is Responding");
            else
              MessageBox.Show("IEXPLORE is Not Responding");
          else
            MessageBox.Show("IEXPLORE is Not Running");
                    
          }
    
        private void btnClose_Click(object sender, System.EventArgs e)
        {
          this.closeBrowser();
        }
    
        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        { //If the browser is still open, close it when the form closes.
          if (Browser!=null)
            this.closeBrowser();
        }
        private void closeBrowser()
        {
          try
          {
            if (procs[0].Responding)
              procs[0].CloseMainWindow();
            else
              procs[0].Kill();
            //Destroy object reference and array.
            this.cleanUp();
          }
          catch 
          {
            MessageBox.Show("Could Not Find the IEXPLORE Process");
          }
        }
        private void Browser_OnQuit()
        { //event delegate - clean up if the browser is closed manually  
          this.cleanUp();
        }
        private void cleanUp()
        {  //Destroy browser reference variable and array.
          Browser = null;
          procs=null;
        }
    
        private void Form1_Load(object sender, System.EventArgs e)
        {/*required method*/}
      }
    
    }
    						
    Note The code should be changed in Visual Studio 2005. For more information, visit the following Microsoft Developer Network (MSDN) Web site: When you create a Windows Forms project, Visual C# adds one form to the project by default. This form is named Form1. The two files that represent the form are named Form1.cs and Form1.designer.cs. You write your code in Form1.cs. The Designer.cs file is where the Windows Forms Designer writes the code that implements all the actions that you performed by adding and removing controls.

    NOTE: The preceding code draws, positions, and names the three buttons on the form automatically, so you do not need to add them manually.
  8. After you paste the code in the Form1.cs code window, you may want to collapse the region that is labeled Windows Form Designer generated code.
  9. Press F5 to build and then run the project.
  10. After Internet Explorer is running, click the buttons on the form to test the code.
back to the top

REFERENCES

For additional information, click the article number below to view the article in the Microsoft Knowledge Base:

304990 Detect if an Application has Stopped Responding by Using Visual Basic .NET

back to the top

Modification Type:MinorLast Reviewed:10/4/2006
Keywords:kbHOWTOmaster kbSample KB304991 kbAudDeveloper