简体   繁体   English

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

[英]How to use AxWebBrowser in console application

I wanna use AxWebBrowser on console application, but it give me following exception: 我想在控制台应用程序上使用AxWebBrowser,但是它给了我以下异常:

Exception of type 'System.Windows.Forms.AxHost+InvalidActiveXStateException' was thrown. 引发了类型为'System.Windows.Forms.AxHost + InvalidActiveXStateException'的异常。

anybody please help me on this by any sample code for using AxWebBrowser in console application c# without any exeption ... 任何人都可以通过任何示例代码在控制台应用程序c#中使用AxWebBrowser的任何示例代码来帮助我,而无需做任何事...

Yes, the [STAThread] attribute is required on your Main() method so that COM is initialized properly to make the main thread a Single Threaded Apartment. 是的,Main()方法上需要[STAThread]属性,以便正确初始化COM,以使主线程成为单线程单元。 That's not all though, you will also need to pump a message loop. 不仅如此,您还需要添加消息循环。 That's a requirement for an STA. 这是STA的要求。 Without one, WebBrowser cannot update its state or run its event handlers, you'll never get the DocumentCompleted event for example. 没有一个,WebBrowser无法更新其状态或运行其事件处理程序,例如,您将永远不会获得DocumentCompleted事件。 You can get a message loop with Application.Run(). 您可以使用Application.Run()获得消息循环。

Your console application is now indistinguishable from a Windows Forms application. 现在,您的控制台应用程序与Windows Forms应用程序是无法区分的。 It is actually easier to get everything right by starting a new project with the Windows Forms application project template, then Project + Properties, Output type = Console Application. 实际上,通过使用Windows Forms应用程序项目模板开始一个新项目,然后选择Project + Properties,输出类型= Console Application,使所有事情都变得正确。 Edit the Application.Run() call in Program.cs so it doesn't create a form. 编辑Program.cs中的Application.Run()调用,使其不会创建表单。 It won't make dealing with Application.Run() any easier, consider a Timer to run code. 它不会使处理Application.Run()更容易,请考虑使用Timer来运行代码。

Add the STAThread attribute to your Main method. STAThread属性添加到您的Main方法。

However, you should not be using the "raw" ActiveX control. 但是,您不应使用“原始” ActiveX控件。

Instead, add a reference to System.Windows.Forms.dll and use the WebBrowser class. 而是,添加对System.Windows.Forms.dll的引用,并使用WebBrowser类。 (Yes, you can do that in a Console app) (是的,您可以在控制台应用程序中执行此操作)


Also, automating IE is not ideal. 另外,自动化IE也不是理想的选择。 You should consider using the WebCLient class. 您应该考虑使用WebCLient类。

My class is as below but in the run time it gives me System.Windows.Forms.AxHost+InvalidActiveXStateException: 我的课如下,但是在运行时,它给了我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;
    }
}

First, the thread in which the control is hosted must be in single-threaded apartment, you can either put the STAThread in your Main method, or create a separated Thread like this: 首先,控件所在的线程必须位于单线程单元中,您可以将STAThread放入Main方法中,也可以创建一个单独的Thread,如下所示:

var thread = new Thread(() =>
{
   //My code
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join(); //Wait for thread termination

Second, you must start a message loop: 其次,您必须开始一个消息循环:

while (true) //Put some exit condition
    System.Windows.Forms.Application.DoEvents();

Third the control must be hosted in a visible form. 第三,控件必须以可见形式托管。 The form must be visible just once, so to avoid "flickering", you can write this code: 该表单必须仅可见一次,为避免“闪烁”,您可以编写以下代码:

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

Finally you might want to disable the "click" sound ( How to disable click sound in WebBrowser Control ) 最后,您可能想禁用“喀哒”声( 如何在WebBrowser控件中禁用喀哒声

The final code: 最终代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM