如何在控制台应用程序中使用AxWebBrowser

时间:2010-01-24 14:03:53

标签: c# console browser axwebbrowser

我想在控制台应用程序上使用AxWebBrowser,但它给了我以下异常:

抛出了类型'System.Windows.Forms.AxHost + InvalidActiveXStateException'的异常。

任何人都可以通过任何在控制台应用程序c#中使用AxWebBrowser的示例代码来帮助我,没有任何例外...

4 个答案:

答案 0 :(得分:1)

是的,Main()方法需要[STAThread]属性,以便正确初始化COM以使主线程成为单线程单元。但这并非全部,您还需要提供消息循环。这是STA的要求。如果没有一个,WebBrowser无法更新其状态或运行其事件处理程序,您将永远不会获得DocumentCompleted事件。您可以使用Application.Run()获得消息循环。

您的控制台应用程序现在与Windows窗体应用程序无法区分。实际上,通过使用Windows窗体应用程序项目模板启动新项目,然后使用Project + Properties,输出类型=控制台应用程序,可以更轻松地完成所有操作。编辑Program.cs中的Application.Run()调用,这样就不会创建表单。它不会更容易处理Application.Run(),考虑使用Timer来运行代码。

答案 1 :(得分:0)

STAThread属性添加到Main方法。

但是,您不应该使用“原始”ActiveX控件。

而是添加对System.Windows.Forms.dll的引用并使用WebBrowser类。 (是的,您可以在控制台应用中执行此操作)


此外,IE的自动化并不理想。您应该考虑使用WebCLient类。

答案 2 :(得分:0)

我的类如下所示,但在运行时它给了我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;
    }
}

答案 3 :(得分:0)

首先,托管控件的线程必须位于单线程单元中,您可以将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();

第三,控件必须以可见的形式托管。表单必须只能看一次,所以为了避免“闪烁”,你可以编写这段代码:

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();

最后,您可能想要禁用“点击”声音(How to disable click sound in WebBrowser Control

最终代码:

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();
    }
}