1

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

引发了“System.Windows.Forms.AxHost+InvalidActiveXStateException”类型的异常。

任何人请通过任何示例代码帮助我在控制台应用程序 c# 中使用 AxWebBrowser 没有任何异常...

4

4 回答 4

1

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

您的控制台应用程序现在与 Windows 窗体应用程序没有区别。通过使用 Windows 窗体应用程序项目模板开始一个新项目,然后是项目 + 属性,输出类型 = 控制台应用程序,实际上更容易得到正确的结果。编辑 Program.cs 中的 Application.Run() 调用,使其不会创建表单。它不会使处理 Application.Run() 变得更容易,考虑一个 Timer 来运行代码。

于 2010-01-24T14:47:06.847 回答
0

STAThread属性添加到您的Main方法中。

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

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


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

于 2010-01-24T14:08:14.157 回答
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;
    }
}
于 2010-01-24T15:18:35.897 回答
0

首先,托管控件的线程必须在单线程单元中,您可以将其放在STAThreadMain 方法中,也可以像这样创建一个单独的线程:

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

最后,您可能想要禁用“点击”声音(如何在 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();
    }
}
于 2014-02-22T14:52:31.563 回答