如何在WebBrowser控件中注入Javascript?

时间:2020-03-06 14:55:52  来源:igfitidea点击:

我已经试过了:

string newScript = textBox1.Text;
HtmlElement head = browserCtrl.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = browserCtrl.Document.CreateElement("script");
lblStatus.Text = scriptEl.GetType().ToString();
scriptEl.SetAttribute("type", "text/javascript");
head.AppendChild(scriptEl);
scriptEl.InnerHtml = "function sayHello() { alert('hello') }";

scriptEl.InnerHtml和scriptEl.InnerText都给出错误:

System.NotSupportedException: Property is not supported on this type of HtmlElement.
   at System.Windows.Forms.HtmlElement.set_InnerHtml(String value)
   at SForceApp.Form1.button1_Click(Object sender, EventArgs e) in d:\jsight\installs\SForceApp\SForceApp\Form1.cs:line 31
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

有没有一种简单的方法可以将脚本注入到dom中?

解决方案

我们要做的是使用Page.RegisterStartupScript(key,script)

有关更多详细信息,请参见此处:http://msdn.microsoft.com/zh-cn/library/aa478975.aspx

我们基本上要做的是构建javascript字符串,将其传递给该方法并为其指定一个唯一的ID(以防我们尝试在页面上将其注册两次。)

编辑:这就是我们所说的触发快乐。随意降低它。 :)

我们始终可以使用" DocumentStream"或者" DocumentText"属性。
对于使用HTML文档,我建议使用HTML Agility Pack。

HTML文档的托管包装没有完全实现所需的功能,因此我们需要使用MSHTML API来完成所需的工作:

1)添加对MSHTML的引用,该引用在COM引用下可能被称为" Microsoft HTML对象库"。

2)添加"使用mshtml;"到名称空间。

3)获取对脚本元素的IHTMLElement的引用:

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;

4)调用insertAdjacentText方法,其第一个参数值为" afterBegin"。此处列出了所有可能的值:

iScriptEl.insertAdjacentText("afterBegin", "function sayHello() { alert('hello') }");

5)现在,我们将能够在scriptEl.InnerText属性中看到代码。

Hth,
理查德

由于某种原因,Richard的解决方案对我而言不起作用(insertAdjacentText失败,并带有异常)。但是,这似乎可行:

HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
element.text = "function sayHello() { alert('hello') }";
head.AppendChild(scriptEl);
webBrowser1.Document.InvokeScript("sayHello");

该答案说明了如何将" IHTMLScriptElement"接口添加到项目中。

如果我们真正想要的只是运行javascript,这将是最简单的(VB .Net):

MyWebBrowser.Navigate("javascript:function foo(){alert('hello');}foo();")

我想这不会"注入"它,但是它将运行函数(如果我们要这样做的话)。 (以防万一我们使问题过于复杂。)并且,如果我们能弄清楚如何注入javascript,请将其放入函数" foo"的主体中,然后让javascript为我们注入。

另外,在.NET 4中,如果使用dynamic关键字,这甚至更加容易:

dynamic document = this.browser.Document;
dynamic head = document.GetElementsByTagName("head")[0];
dynamic scriptEl = document.CreateElement("script");
scriptEl.text = ...;
head.AppendChild(scriptEl);

这是使用mshtml的解决方案

IHTMLDocument2 doc = new HTMLDocumentClass();
doc.write(new object[] { File.ReadAllText(filePath) });
doc.close();

IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)doc.all.tags("head")).item(null, 0);
IHTMLScriptElement scriptObject = (IHTMLScriptElement)doc.createElement("script");
scriptObject.type = @"text/javascript";
scriptObject.text = @"function btn1_OnClick(str){
    alert('you clicked' + str);
}";
((HTMLHeadElementClass)head).appendChild((IHTMLDOMNode)scriptObject);