Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WebBrowser控件中注入Javascript?_C#_Javascript_.net_Winforms_Webbrowser Control - Fatal编程技术网

C# 如何在WebBrowser控件中注入Javascript?

C# 如何在WebBrowser控件中注入Javascript?,c#,javascript,.net,winforms,webbrowser-control,C#,Javascript,.net,Winforms,Webbrowser Control,我试过这个: string newScript = textBox1.Text; HtmlElement head = browserCtrl.Document.GetElementsByTagName("head")[0]; HtmlElement scriptEl = browserCtrl.Document.CreateElement("script"); lblStatus.Text = scriptEl.GetType().ToString(); scriptEl.SetAttribu

我试过这个:

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) :

有关更多详细信息,请参见此处:

基本上,您要做的是构建javascript字符串,将其传递给该方法,并为其提供一个唯一的id(以防您尝试在一个页面上注册它两次)

编辑:这就是你所说的触发快乐。请随意写下来。:)

您始终可以使用“DocumentStream”或“DocumentText”属性。
对于使用HTML文档,我建议使用。

HTML文档的托管包装器不能完全实现您需要的功能,因此您需要使用MSHTML API来实现您想要的功能:

1) 添加对MSHTML的引用,它可能在COM引用下被称为“Microsoft HTML对象库”

2) 添加“使用mshtml;”到您的名称空间

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

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;
4) 调用insertAdjacentText方法,第一个参数值为“afterBegin”。列出了所有可能的值:

5) 现在,您可以在scriptEl.InnerText属性中看到代码

嗯,,
Richard

由于某种原因,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):


我想这不会“注入”它,但它会运行你的函数,如果你想要的话。(以防万一你把问题复杂化了。)如果你能想出如何注入javascript,把它放到函数“foo”的主体中,让javascript为你注入。

此外,在.NET 4中,如果你使用动态关键字,这会更容易:

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);
(在.NET 4/Windows窗体应用程序中测试)


编辑:修复了功能集中的案例问题

我认为从c#向WebBrowser控件HTML文档中注入Javascript最简单的方法是调用“execScript”方法,将要注入的代码作为参数

在本例中,在全局范围内注入并执行javascript代码:

var jsCode="alert('hello world from injected code');";
WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });
如果要延迟执行,请插入函数并在以下时间后调用它们:

var jsCode="function greet(msg){alert(msg);};";
WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });
...............
WebBrowser.Document.InvokeScript("greet",new object[] {"hello world"});
这对Windows窗体和WPF WebBrowser控件有效

此解决方案不是跨浏览器的,因为“execScript”仅在IE和Chrome中定义。但问题是关于微软WebBrowser控件,IE是唯一受支持的

要使用有效的跨浏览器方法注入javascript代码,请使用new关键字创建函数对象。本例使用注入的代码创建一个匿名函数并执行它(javascript实现闭包,该函数可以访问全局空间,而不会造成局部变量污染)

当然,您可以延迟执行:

var jsCode="alert('hello world');";
var inserted=new Function(code);
.................
inserted();

希望对您有所帮助

如果您试图从WebBrowser控件中加载的页面中检索变量的值,下面是一个VB.Net示例

步骤1)将项目中的COM引用添加到Microsoft HTML对象库

步骤2)接下来,将此VB.Net代码添加到Form1以导入mshtml库:
导入mshtml

步骤3)将此VB.Net代码添加到“公共类表单1”行上方:

步骤4)将WebBrowser控件添加到项目中

步骤5)将此VB.Net代码添加到Form1_加载函数:
WebBrowser1.ObjectForScript=Me

步骤6)添加此VB.Net sub,它将向网页的Javascript中注入函数“CallbackGetVar”:

Public Sub-InjectCallbackGetVar(ByRef wb作为WebBrowser)
昏头昏脑
将脚本设置为HtmleElement
作为IHTMLScript元素的Dim DOMELENT
head=wb.Document.GetElementsByTagName(“head”)(0)
script=wb.Document.CreateElement(“脚本”)
domElement=script.domElement
domElement.type=“text/javascript”
domElement.text=“函数CallbackGetVar(myVar){window.external.Callback_GetVar(eval(myVar));}”
head.AppendChild(脚本)
端接头
步骤7)添加以下VB.Net子脚本,Javascript将在调用时查找该子脚本:

公共子回调\u GetVar(ByVal vVar作为字符串)
调试打印(vVar)
端接头
步骤8)最后,要调用Javascript回调,请在按下按钮时或在您喜欢的任何位置添加此VB.Net代码:

Private子按钮1\u单击(ByVal sender作为System.Object,ByVal e作为System.EventArgs)处理按钮1。单击
WebBrowser1.Document.InvokeScript(“CallbackGetVar”,New Object(){“NameOfVarToRetrieve”})
端接头

第9步)如果这让您感到惊讶,那么您可能需要阅读第6步中使用的Javascript“eval”函数,这就是实现这一点的原因。它将获取一个字符串,并确定是否存在具有该名称的变量,如果存在,则返回该变量的值。

这是我处理此问题后发现的最简单的方法:

string javascript = "alert('Hello');";
// or any combination of your JavaScript commands
// (including function calls, variables... etc)

// WebBrowser webBrowser1 is what you are using for your web browser
webBrowser1.Document.InvokeScript("eval", new object[] { javascript });
全局JavaScript函数
eval(str)
所做的是解析并执行str中编写的任何内容。 选中。

作为的后续操作,这是的最低定义,不需要包括其他类型库:

[ComImport, ComVisible(true), Guid(@"3050f28b-98b5-11cf-bb82-00aa00bdce0b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
[TypeLibType(TypeLibTypeFlags.FDispatchable)]
public interface IHTMLScriptElement
{
    [DispId(1006)]
    string text { set; [return: MarshalAs(UnmanagedType.BStr)] get; }
}
因此WebBrowser控件派生类中的完整代码如下所示:

protected override void OnDocumentCompleted(
    WebBrowserDocumentCompletedEventArgs e)
{
    base.OnDocumentCompleted(e);

    // Disable text selection.
    var doc = Document;
    if (doc != null)
    {
        var heads = doc.GetElementsByTagName(@"head");
        if (heads.Count > 0)
        {
            var scriptEl = doc.CreateElement(@"script");
            if (scriptEl != null)
            {
                var element = (IHTMLScriptElement)scriptEl.DomElement;
                element.text =
                    @"function disableSelection()
                    { 
                        document.body.onselectstart=function(){ return false; }; 
                        document.body.ondragstart=function() { return false; };
                    }";
                heads[0].AppendChild(scriptEl);
                doc.InvokeScript(@"disableSelection");
            }
        }
    }
}

如果需要注入整个文件,则可以使用以下方法:

webBrowser.Document.InvokeScript("execScript", new object[] { "alert(123)", "JavaScript" })
与Browser.Document
将头部调暗为HtmleElement=.GetElementsByTagName(“头部”)(0)
将脚本设置为HtmleElement=.CreateElement(“脚本”)
将拖缆变暗为新的StreamReader()
使用拖缆
Script.SetAttribute(“text”,Streamer.ReadToEnd())
终端使用
Head.AppendChild(脚本)
.InvokeScript()
以
记住导入
System.IO
以使用
string javascript = "alert('Hello');";
// or any combination of your JavaScript commands
// (including function calls, variables... etc)

// WebBrowser webBrowser1 is what you are using for your web browser
webBrowser1.Document.InvokeScript("eval", new object[] { javascript });
[ComImport, ComVisible(true), Guid(@"3050f28b-98b5-11cf-bb82-00aa00bdce0b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
[TypeLibType(TypeLibTypeFlags.FDispatchable)]
public interface IHTMLScriptElement
{
    [DispId(1006)]
    string text { set; [return: MarshalAs(UnmanagedType.BStr)] get; }
}
protected override void OnDocumentCompleted(
    WebBrowserDocumentCompletedEventArgs e)
{
    base.OnDocumentCompleted(e);

    // Disable text selection.
    var doc = Document;
    if (doc != null)
    {
        var heads = doc.GetElementsByTagName(@"head");
        if (heads.Count > 0)
        {
            var scriptEl = doc.CreateElement(@"script");
            if (scriptEl != null)
            {
                var element = (IHTMLScriptElement)scriptEl.DomElement;
                element.text =
                    @"function disableSelection()
                    { 
                        document.body.onselectstart=function(){ return false; }; 
                        document.body.ondragstart=function() { return false; };
                    }";
                heads[0].AppendChild(scriptEl);
                doc.InvokeScript(@"disableSelection");
            }
        }
    }
}
HtmlElement script = this.WebNavegador.Document.CreateElement("SCRIPT");
script.SetAttribute("TEXT", "function GetNameFromBrowser() {" + 
"return 'My name is David';" + 
"}");

this.WebNavegador.Document.Body.AppendChild(script);
string myNameIs = (string)this.WebNavegador.Document.InvokeScript("GetNameFromBrowser");
webBrowser.Document.InvokeScript("execScript", new object[] { "alert(123)", "JavaScript" })