Pregunta

He intentado esto:

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 y scriptEl.InnerText dan errores:

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)

¿Hay una manera fácil de inyectar un script en el dom?

¿Fue útil?

Solución

Por alguna razón, la solución de Richard no funcionó de mi parte (insertAdarestText falló con una excepción). Sin embargo, esto parece funcionar:

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

Esta respuesta explica cómo obtener la interfaz IHTMLScriptElement en su proyecto.

Otros consejos

HtmlDocument doc = browser.Document;
HtmlElement head = doc.GetElementsByTagName("head")[0];
HtmlElement s = doc.CreateElement("script");
s.SetAttribute("text","function sayHello() { alert('hello'); }");
head.AppendChild(s);
browser.Document.InvokeScript("sayHello");

(probado en .NET 4 / Windows Forms App)

Editar: Se corrigió un problema de mayúsculas y minúsculas en el conjunto de funciones.

Aquí está la forma más fácil que encontré después de trabajar en esto:

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

Lo que la función global de JavaScript eval(str) hace es analizar y ejecutar lo que esté escrito en str. Consulte w3schools ref aquí .

Además, en .NET 4 esto es aún más fácil si usa la palabra clave dinámica:

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

Si todo lo que realmente desea es ejecutar javascript, esto sería más fácil (VB .Net):

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

Supongo que esto no " inyectar " pero ejecutará tu función, si eso es lo que buscas. (Solo en caso de que haya complicado demasiado el problema.) Y si puede encontrar la manera de inyectar en JavaScript, colóquelo en el cuerpo de la función & Quot; foo & Quot; y deja que el javascript haga la inyección por ti.

El contenedor administrado para el documento HTML no implementa completamente la funcionalidad que necesita, por lo que debe sumergirse en la API MSHTML para lograr lo que desea:

1) Agregue una referencia a MSHTML, que probablemente se denominará " Microsoft HTML Object Library " bajo COM referencias.

2) Agregue 'usando mshtml;' a sus espacios de nombres.

3) Obtenga una referencia al elemento IHTMLElement de su elemento de script:

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;

4) Llame al método insertAdarestText, con el primer valor de parámetro de " afterBegin " ;. Todos los valores posibles se enumeran aquí :

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

5) Ahora podrá ver el código en la propiedad scriptEl.InnerText.

Hth, Richard

Como seguimiento de la respuesta aceptada , esta es una definición mínima de IHTMLScriptElement interfaz que no requiere incluir un tipo adicional bibliotecas:

[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; }
}

Entonces, un código completo dentro de una clase derivada de control WebBrowser se vería así:

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

esta es una solución usando 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);

Creo que el método más simple para inyectar Javascript en un documento HTML de control de WebBrowser desde c # es invocar " execStrip " método con el código que se inyectará como argumento.

En este ejemplo, el código javascript se inyecta y ejecuta a nivel global:

var jsCode="alert('hello world from injected code');";
WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });

Si desea retrasar la ejecución, inyecte funciones y llámelas después de:

var jsCode="function greet(msg){alert(msg);};";
WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });
...............
WebBrowser.Document.InvokeScript("greet",new object[] {"hello world"});

Esto es válido para Windows Forms y controles WPF WebBrowser.

Esta solución no es un navegador cruzado porque " execScript " se define solo en IE y Chrome. Pero la pregunta es sobre los controles de Microsoft WebBrowser e IE es el único compatible.

Para un método de navegador cruzado válido para inyectar código javascript, cree un objeto Function con la nueva palabra clave. Este ejemplo crea una función anónima con código inyectado y la ejecuta (JavaScript implementa cierres y la función tiene acceso al espacio global sin contaminación variable local).

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

Por supuesto, puede retrasar la ejecución:

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

Espero que ayude

Usé esto: D

HtmlElement script = this.WebNavegador.Document.CreateElement("SCRIPT");
script.SetAttribute("TEXT", "function GetNameFromBrowser() {" + 
"return 'My name is David';" + 
"}");

this.WebNavegador.Document.Body.AppendChild(script);

Luego puede ejecutar y obtener el resultado con:

string myNameIs = (string)this.WebNavegador.Document.InvokeScript("GetNameFromBrowser");

Espero ser útil

Aquí hay un ejemplo de VB.Net si está intentando recuperar el valor de una variable desde una página cargada en un control WebBrowser.

Paso 1) Agregue una referencia COM en su proyecto a la Biblioteca de objetos HTML de Microsoft

Paso 2) A continuación, agregue este código VB.Net a su Form1 para importar la biblioteca mshtml:
        Importa mshtml

Paso 3) Agregue este código VB.Net sobre su " Public Class Form1 " línea:
        < System.Runtime.InteropServices.ComVisibleAttribute (True) >

Paso 4) Agregue un control WebBrowser a su proyecto

Paso 5) Agregue este código VB.Net a su función Form1_Load:
        WebBrowser1.ObjectForScripting = Me

Paso 6) Agregue este sub VB.Net que inyectará una función " CallbackGetVar " en el Javascript de la página web:

Public Sub InjectCallbackGetVar(ByRef wb As WebBrowser)
    Dim head As HtmlElement
    Dim script As HtmlElement
    Dim domElement As IHTMLScriptElement

    head = wb.Document.GetElementsByTagName("head")(0)
    script = wb.Document.CreateElement("script")
    domElement = script.DomElement
    domElement.type = "text/javascript"
    domElement.text = "function CallbackGetVar(myVar) { window.external.Callback_GetVar(eval(myVar)); }"
    head.AppendChild(script)
End Sub

Paso 7) Agregue el siguiente sub VB.Net que el Javascript buscará cuando se invoque:

Public Sub Callback_GetVar(ByVal vVar As String)
    Debug.Print(vVar)
End Sub

Paso 8) Finalmente, para invocar la devolución de llamada de Javascript, agregue este código VB.Net cuando se presiona un botón, o donde desee:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    WebBrowser1.Document.InvokeScript("CallbackGetVar", New Object() {"NameOfVarToRetrieve"})
End Sub

Paso 9) Si le sorprende que esto funcione, puede leer el Javascript " eval " función, utilizada en el Paso 6, que es lo que hace esto posible. Tomará una cadena y determinará si existe una variable con ese nombre y, de ser así, devolverá el valor de esa variable.

Siempre puede usar un " DocumentStream " o " DocumentText " propiedad. Para trabajar con documentos HTML, recomiendo un HTML Agility Pack .

Lo que quiere hacer es usar Page.RegisterStartupScript (clave, script) :

Ver aquí para más detalles: http://msdn.microsoft.com /en-us/library/aa478975.aspx

Lo que básicamente hace es construir su cadena de JavaScript, pasarla a ese método y darle una identificación única (en caso de que intente registrarla dos veces en una página).

EDITAR: Esto es lo que llamas gatillo feliz. Siéntase libre de bajarlo. :)

yo uso esto:

webBrowser.Document.InvokeScript("execScript", new object[] { "alert(123)", "JavaScript" })

Si necesita inyectar un archivo completo, puede usar esto:

With Browser.Document
   Dim Head As HtmlElement = .GetElementsByTagName("head")(0)
   Dim Script As HtmlElement = .CreateElement("script")
   Dim Streamer As New StreamReader(<Here goes path to file as String>)
   Using Streamer
       Script.SetAttribute("text", Streamer.ReadToEnd())
   End Using
   Head.AppendChild(Script)
   .InvokeScript(<Here goes a method name as String and without parentheses>)
End With

Recuerde importar System.IO para usar StreamReader. Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top