コンソール アプリケーションで AxWebBrowser を使用したいのですが、次の例外が発生します。
タイプ 'System.Windows.Forms.AxHost+InvalidActiveXStateException' の例外がスローされました。
誰でも、例外なしでコンソール アプリケーション c# で AxWebBrowser を使用するためのサンプル コードでこれについて私を助けてください ...
コンソール アプリケーションで AxWebBrowser を使用したいのですが、次の例外が発生します。
タイプ 'System.Windows.Forms.AxHost+InvalidActiveXStateException' の例外がスローされました。
誰でも、例外なしでコンソール アプリケーション c# で AxWebBrowser を使用するためのサンプル コードでこれについて私を助けてください ...
はい、メイン スレッドをシングル スレッド アパートメントにするために COM が適切に初期化されるように、Main() メソッドに [STAThread] 属性が必要です。それだけではありませんが、メッセージ ループをポンピングする必要もあります。これは STA の要件です。これがないと、WebBrowser はその状態を更新したり、イベント ハンドラーを実行したりできません。たとえば、DocumentCompleted イベントを取得することはできません。Application.Run() でメッセージ ループを取得できます。
コンソール アプリケーションは、Windows フォーム アプリケーションと見分けがつかなくなりました。実際には、Windows フォーム アプリケーション プロジェクト テンプレートを使用して新しいプロジェクトを開始し、次に Project + Properties、Output type = Console Application を使用して、すべてを適切に行う方が簡単です。Program.cs の Application.Run() 呼び出しを編集して、フォームが作成されないようにします。Application.Run() の処理が簡単になるわけではありません。タイマーを使用してコードを実行することを検討してください。
STAThread
メソッドに属性を追加しますMain
。
ただし、「生の」ActiveX コントロールは使用しないでください。
代わりに、System.Windows.Forms.dll への参照を追加し、WebBrowser
クラスを使用します。(はい、コンソール アプリで実行できます)
また、IE の自動化は理想的ではありません。WebCLient
クラスの使用を検討する必要があります。
まず、コントロールがホストされているスレッドは、シングル スレッド アパートメントにある必要がありSTAThread
ます。 Main メソッドに配置するか、次のように別の Thread を作成できます。
var thread = new Thread(() =>
{
//My code
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join(); //Wait for thread termination
次に、メッセージ ループを開始する必要があります。
while (true) //Put some exit condition
System.Windows.Forms.Application.DoEvents();
3 番目に、コントロールを可視フォームでホストする必要があります。フォームは一度だけ表示される必要があるため、「ちらつき」を避けるために、次のコードを記述できます。
var browser = new AxWebBrowser();
var hostForm = new Form();
//Set form 0 size, without any control box / title / icon
hostForm.Width = 0;
hostForm.Height = 0;
hostForm.ShowInTaskbar = false;
hostForm.ControlBox = false;
hostForm.ShowIcon = false;
hostForm.MinimizeBox = false;
hostForm.MaximizeBox = false;
//Add browser control
hostForm.Controls.Add(browser);
//Show and immediately hide
hostForm.Show();
hostForm.Hide();
最後に、「クリック」音を無効にすることができます ( WebBrowser コントロールでクリック音を無効にする方法) 。
最終的なコード:
class Program
{
[STAThread]
static void Main(string[] args)
{
URLSecurityZoneAPI.InternetSetFeatureEnabled(URLSecurityZoneAPI.InternetFeaturelist.DISABLE_NAVIGATION_SOUNDS, URLSecurityZoneAPI.SetFeatureOn.PROCESS, true);
var browser = new AxWebBrowser();
var hostForm = new Form();
hostForm.Width = 0;
hostForm.Height = 0;
hostForm.ShowInTaskbar = false;
hostForm.ControlBox = false;
hostForm.ShowIcon = false;
hostForm.MinimizeBox = false;
hostForm.MaximizeBox = false;
hostForm.Controls.Add(browser);
hostForm.Show();
hostForm.Hide();
browser.DocumentComplete += delegate(object sender, DWebBrowserEvents2_DocumentCompleteEvent e)
{
var doc = (IHTMLDocument3)browser.Document;
Console.WriteLine(doc.documentElement.innerHTML);
};
browser.Navigate("www.google.com");
while (true)
System.Windows.Forms.Application.DoEvents();
}
}
私のクラスは次のとおりですが、実行時に System.Windows.Forms.AxHost+InvalidActiveXStateException が表示されます。
public class Browse
{
private static AxWebBrowser wBrowser;
public static Result StartBrowse(string url)
{
var validUri = (url.Contains("http://") ? url : "http://" + url);
wBrowser = new AxWebBrowser();
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(AxWebBrowser));
((ISupportInitialize) (wBrowser)).BeginInit();
wBrowser.OcxState = ((AxHost.State)(resources.GetObject("wBrowser.OcxState")));
wBrowser.NewWindow2 += wBrowser_NewWindow2;
wBrowser.NewWindow3 += wBrowser_NewWindow3;
wBrowser.DocumentComplete += wBrowser_DocumentComplete;
wBrowser.DownloadComplete += wBrowser_DownloadComplete;
if (string.IsNullOrEmpty(html) || validUri != url)
{
object empty = System.Reflection.Missing.Value;
wBrowser.Silent = true;
wBrowser.Navigate(validUri, ref empty, ref empty, ref empty, ref empty);
}
return null;
}
static void wBrowser_DownloadComplete(object sender, EventArgs e)
{
doAlgorithm();
}
static void wBrowser_DocumentComplete(object sender, DWebBrowserEvents2_DocumentCompleteEvent e)
{
doAlgorithm();
}
static void wBrowser_NewWindow3(object sender, DWebBrowserEvents2_NewWindow3Event e)
{
e.cancel = true;
}
static void wBrowser_NewWindow2(object sender, DWebBrowserEvents2_NewWindow2Event e)
{
e.cancel = true;
}
}