He probado 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)
¿Existe una manera fácil de inyectar un script en el dom?
c#
javascript
.net
winforms
webbrowser-control
jsight
fuente
fuente
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 la aplicación .NET 4 / Windows Forms)
Editar: problema de caso fijo en el conjunto de funciones.
fuente
IHTMLSCriptElement
dependencia.Esta es 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 hace la función JavaScript global
eval(str)
es analizar y ejecutar lo que esté escrito en str. Consulte la referencia de w3schools aquí .fuente
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);
fuente
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 lo "inyectaría" pero ejecutará su función, si eso es lo que busca. (En caso de que haya complicado demasiado el problema). Y si puede averiguar cómo inyectar en javascript, colóquelo en el cuerpo de la función "foo" y deje que javascript haga la inyección por usted.
fuente
El contenedor administrado para el documento HTML no implementa completamente la funcionalidad que necesita, por lo que debe sumergirse en la API de MSHTML para lograr lo que desea:
1) Agregue una referencia a MSHTML, que probablemente se llamará "Biblioteca de objetos HTML de Microsoft" en las referencias COM .
2) Agregue 'usando mshtml;' a sus espacios de nombres.
3) Obtenga una referencia al IHTMLElement de su elemento de script:
4) Llame al método insertAdherentText, con el primer valor de parámetro "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
fuente
Como seguimiento de la respuesta aceptada , esta es una definición mínima de la
IHTMLScriptElement
interfaz que no requiere incluir bibliotecas de tipos adicionales:[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"); } } } }
fuente
Creo que el método más simple para inyectar Javascript en un documento HTML de control de WebBrowser desde c # es invocar el método "execScript" 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:
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 los controles de Windows Forms y WPF WebBrowser.
Esta solución no es para varios navegadores porque "execScript" se define solo en IE y Chrome. Pero la pregunta es sobre los controles de Microsoft WebBrowser y IE es el único compatible.
Para que un método de navegador cruzado válido inyecte código javascript, cree un objeto Función 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 de variables locales).
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 eso ayude
fuente
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);
fuente
((HTMLHeadElement)head).appendChild((IHTMLDOMNode)scriptObject);
que obtendrá errores de lo contrario.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 de ayuda
fuente
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:
Imports mshtml
Paso 3) Agregue este código VB.Net encima de su línea "Public Class Form1":
<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 luego buscará Javascript 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, es posible que desee leer sobre la función "eval" de Javascript, utilizada en el Paso 6, que es lo que lo hace posible. Tomará una cadena y determinará si existe una variable con ese nombre y, de ser así, devolverá el valor de esa variable.
fuente
Siempre puede utilizar una propiedad "DocumentStream" o "DocumentText". Para trabajar con documentos HTML, recomiendo un HTML Agility Pack .
fuente
yo uso esto:
webBrowser.Document.InvokeScript("execScript", new object[] { "alert(123)", "JavaScript" })
fuente
Lo que quieres hacer es usar Page.RegisterStartupScript (clave, script):
Consulte aquí para obtener 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éntete libre de bajarlo. :)
fuente
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 elStreamReader
. Espero que esto ayude.fuente
input type="file"
sección?