开发者

How to use AxWebBrowser in console application

开发者 https://www.devze.com 2022-12-18 10:07 出处:网络
I wanna use A开发者_如何学编程xWebBrowser on console application, but it give me following exception:

I wanna use A开发者_如何学编程xWebBrowser on console application, but it give me following exception:

Exception of type 'System.Windows.Forms.AxHost+InvalidActiveXStateException' was thrown.

anybody please help me on this by any sample code for using AxWebBrowser in console application c# without any exeption ...


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. That's not all though, you will also need to pump a message loop. That's a requirement for an STA. Without one, WebBrowser cannot update its state or run its event handlers, you'll never get the DocumentCompleted event for example. You can get a message loop with Application.Run().

Your console application is now indistinguishable from a Windows Forms application. 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. Edit the Application.Run() call in Program.cs so it doesn't create a form. It won't make dealing with Application.Run() any easier, consider a Timer to run code.


Add the STAThread attribute to your Main method.

However, you should not be using the "raw" ActiveX control.

Instead, add a reference to System.Windows.Forms.dll and use the WebBrowser class. (Yes, you can do that in a Console app)


Also, automating IE is not ideal. You should consider using the WebCLient class.


My class is as below but in the run time it gives me 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:

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)

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号