我想在控制台应用程序上使用AxWebBrowser,但它给了我以下异常:
抛出了类型'System.Windows.Forms.AxHost + InvalidActiveXStateException'的异常。
任何人都可以通过任何在控制台应用程序c#中使用AxWebBrowser的示例代码来帮助我,没有任何例外...
答案 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();
}
}