0

タブ コントロールを備えたデスクトップ アプリケーション (フォーム) があり、タブと新しいカスタム Web ブラウザー コントロールを割り当てます。これらのタブを約10個開きます。それぞれが約 100 ~ 500 の異なるページにアクセスします。

問題は、1 つの Web ブラウザー コントロールに問題があると、プログラム全体がシャットダウンされることです。

問題のある Web ブラウザー コントロールを閉じて、その場所に新しいコントロールを開きたいと考えています。

クラッシュまたは応答しない Web ブラウザー コントロールをキャッチするためにサブスクライブする必要があるイベントはありますか?

Windows 7 (フォーム)、.NET Framework v4 で C# を使用しています。

================================================== =============

更新: 1 - タブ付き WebBrowser の例

ここに私が持っているコードと、最も基本的な方法で webbrowser コントロールを使用する方法があります。

  1. 新しいフォーム プロジェクトを作成し、SimpleWeb という名前を付けます。
  2. 新しいクラスを追加し、myWeb.cs という名前を付けます。使用するコードは次のとおりです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Policy;

namespace SimpleWeb
{
    //inhert all of webbrowser
    class myWeb : WebBrowser
    {

        public myWeb()
        {
            //no javascript errors
            this.ScriptErrorsSuppressed = true;

            //Something we want set?
            AssignEvents();
        }

        //keep near the top
        private void AssignEvents()
        {

            //assign WebBrowser events to our custom methods
            Navigated += myWeb_Navigated;
            DocumentCompleted += myWeb_DocumentCompleted;
            Navigating += myWeb_Navigating;
            NewWindow += myWeb_NewWindow;

        }


        #region Events
        //List of events:http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser_events%28v=vs.100%29.aspx

        //Fired when a new windows opens
        private void myWeb_NewWindow(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //cancel all popup windows
            e.Cancel = true;
            //beep to let you know canceled new window
            Console.Beep(9000, 200);
        }


        //Fired before page is navigated (not sure if its before or during?)
        private void myWeb_Navigating(object sender, System.Windows.Forms.WebBrowserNavigatingEventArgs args)
        {

        }

        //Fired after page is navigated (but not loaded)
        private void myWeb_Navigated(object sender, System.Windows.Forms.WebBrowserNavigatedEventArgs args)
        {

        }


        //Fired after page is loaded (Catch 22 - Iframes could be considered a page, can fire more than once. Ads are good examples)
        private void myWeb_DocumentCompleted(System.Object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs args)
        {

        }


        #endregion



        //Answer supplied by mo. (modified)?
        public void OpenUrl(string url)
        {
            try
            {
                //this.OpenUrl(url);
                this.Navigate(url);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Your App Crashed! Because = " + ex.ToString());
                //MyApplication.HandleException(ex);
            }
        }



        //Keep near the bottom
        private void RemoveEvents()
        {
            //Remove Events
            Navigated -= myWeb_Navigated;
            DocumentCompleted -= myWeb_DocumentCompleted;
            Navigating -= myWeb_Navigating;
            NewWindow -= myWeb_NewWindow;
        }
    }
}
  1. Form1 で、標準の tabControl をドラッグし、ドックを塗りつぶすように設定します。必要に応じて、タブ コレクションに移動し、事前設定されたタブを削除できます。

  2. Form1 を右クリックし、[コードの表示] を選択して、このコードに置き換えます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using mshtml;

namespace SimpleWeb
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();


            //Load Up 10 Tabs
            for (int i = 0; i <= 10; i++)
            {
                newTab("Test_" + i, "http://wwww.yahoo.com");

            }
        }


        private void newTab(string Title, String Url)
        {

            //Create a new Tab
            TabPage newTab = new TabPage();
            newTab.Name = Title;
            newTab.Text = Title;

            //create webbrowser Instance
            myWeb newWeb = new myWeb();

            //Add webbrowser to new tab
            newTab.Controls.Add(newWeb);
            newWeb.Dock = DockStyle.Fill;

            //Add New Tab to Tab Pages
            tabControl1.TabPages.Add(newTab);

            newWeb.OpenUrl(Url);


        }
    }
}

プロジェクトを保存して実行します。

moによる以下の回答を使用してください。、最初の URL は問題なく閲覧できますが、ユーザーがクリックするすべての URL についてはどうでしょうか。それらをどのように確認しますか?

ページ上のすべての html 要素にイベントを追加したくないので、無限ループを発生させずにナビゲートする前に、関数 OpenUrl を介して新しい URL を実行する方法が必要です。

ありがとう。

4

1 に答える 1

2

AppDomain.UnhandledExceptionまたはApplication.ThreadExceptionイベントを使用できます。

ただし、この方法で例外を処理すると、アプリケーションで無効な状態になる可能性があります。

これらの例外がいつ発生するか説明していただけますか。
それらはメソッドを実行した結果ですか?

次に、呼び出し元のメソッドでエラーを処理する方がはるかに優れています。

void OpenUrl(Url url)
{
   try
   {
       var webBrowser = GetWebBrowser(tabControl.SelectedTab);
       webBrowser.OpenUrl(url);
   }
   catch(SpecificException ex)
   {
       MyApplication.HandleException(ex);
   }
}

あなたのコメントに関して、これを試してください:

try
{
   myCustomWebbrowser.Navigate("yahoo.com");
}
catch(Exception ex) //catch specific exceptions here (catch all is a bad practice)
{
   MessageBox.Alert(ex.Message); //just for testing.
}

この記事はあなたを助けるはずです:

private void AssignEvents()
{
  Navigated += myWeb_Navigated;
  DocumentCompleted += myWeb_DocumentCompleted;
  Navigating += myWeb_Navigating;
  NewWindow += myWeb_NewWindow;
  DownloadComplete += myWen_DownloadComplete;
}

void myWen_DownloadComplete(object sender, EventArgs e)
{
  // Check wheter the document is available (it should be)
  if (Document != null)
    // Subscribe to the Error event
    Document.Window.Error += myWeb_Window_Error;
}

void myWeb_Window_Error(object sender, HtmlElementErrorEventArgs e)
{
  // We got a script error, record it
  ScriptErrorManager.Instance.RegisterScriptError(e.Url, 
                           e.Description, e.LineNumber);
  // Let the browser know we handled this error.
  e.Handled = true;
}
于 2012-09-01T21:25:01.870 に答える