Question

J'ai essayé ceci:

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 et scriptEl.InnerText donnent tous deux des erreurs:

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-t-il un moyen simple d’injecter un script dans le domaine?

Était-ce utile?

La solution

Pour une raison quelconque, la solution de Richard ne fonctionnait pas de mon côté (insertAdjacentText a échoué avec une exception). Cela semble cependant fonctionner:

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

Cette réponse explique comment intégrer l'interface IHTMLScriptElement dans votre projet.

Autres conseils

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

(testé dans .NET 4 / Windows Forms App)

Modifier: problème de casse résolu dans le jeu de fonctions.

Voici le moyen le plus simple que j'ai trouvé après avoir travaillé sur ceci:

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

La fonction JavaScript globale eval(str) permet d'analyser et d'exécuter tout ce qui est écrit dans str. Consultez les les références de w3schools ici .

De plus, dans .NET 4, cela est encore plus facile si vous utilisez le mot clé dynamique:

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

Si tout ce que vous voulez, c'est exécuter du javascript, c'est plus simple (VB .Net):

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

Je suppose que cela ne serait pas & "injecter &"; mais ça va exécuter votre fonction, si c'est ce que vous recherchez. (Juste au cas où vous auriez trop compliqué le problème.) Et si vous savez comprendre comment injecter du javascript, mettez cela dans le corps de la fonction & "; Foo &"; et laissez le javascript faire l'injection pour vous.

Le wrapper géré pour le document HTML n'implémente pas complètement la fonctionnalité dont vous avez besoin, vous devez donc plonger dans l'API MSHTML pour obtenir ce que vous souhaitez:

1) Ajoutez une référence à MSHTML, qui s'appellera probablement " Bibliothèque d'objets Microsoft HTML " sous COM références.

2) Ajoutez 'using mshtml;' à vos espaces de noms.

3) Obtenez une référence au IHTMLElement de votre élément de script:

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;

4) Appelez la méthode insertAdjacentText, avec la première valeur de paramètre de " afterBegin " ;. Toutes les valeurs possibles sont répertoriées ici :

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

5) Vous pourrez maintenant voir le code dans la propriété scriptEl.InnerText.

Hth, Richard

Pour faire suite à la réponse acceptée , il s'agit d'une définition minimale de la IHTMLScriptElement interface sans qu'il soit nécessaire d'inclure un type supplémentaire bibliothèques:

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

Ainsi, un code complet dans une classe dérivée du contrôle WebBrowser ressemblerait à:

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

Ceci est une solution utilisant 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);

Je pense que la méthode la plus simple pour injecter du code Javascript dans un document HTML de WebBrowser Control à partir de c # consiste à appeler le " execStrip & "; méthode avec le code à injecter comme argument.

Dans cet exemple, le code javascript est injecté et exécuté à l'échelle globale:

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

Si vous souhaitez retarder l'exécution, injectez des fonctions et appelez-les après:

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

Ceci est valable pour les contrôles Windows Forms et WPF WebBrowser.

Cette solution n'est pas inter-navigateur car " execScript " est défini uniquement dans IE et Chrome. Mais la question concerne les contrôles Microsoft WebBrowser et IE est le seul supporté.

Pour une méthode inter-navigateurs valide permettant l’injection de code javascript, créez un objet Function avec le nouveau mot-clé. Cet exemple crée une fonction anonyme avec du code injecté et l'exécute (javascript implémente des fermetures et la fonction a accès à un espace global sans pollution par des variables locales).

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

Bien sûr, vous pouvez retarder l'exécution:

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

J'espère que ça aide

J'ai utilisé ceci: D

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

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

Ensuite, vous pouvez exécuter et obtenir le résultat avec:

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

J'espère être utile

Voici un exemple VB.Net si vous essayez d'extraire la valeur d'une variable depuis une page chargée dans un contrôle WebBrowser.

Étape 1) Ajoutez une référence COM dans votre projet à la bibliothèque d'objets Microsoft HTML

Étape 2) Ajoutez ensuite ce code VB.Net à votre Form1 pour importer la bibliothèque mshtml:
        Importation mshtml

Étape 3) Ajoutez ce code VB.Net au-dessus de votre " Classe publique Form1 " ligne:
        < System.Runtime.InteropServices.ComVisibleAttribute (True) >

Étape 4) Ajoutez un contrôle WebBrowser à votre projet

Étape 5) Ajoutez ce code VB.Net à votre fonction Form1_Load:
        WebBrowser1.ObjectForScripting = Me

Étape 6) Ajoutez ce sous-réseau VB.Net qui injectera une fonction & "CallbackGetVar &"; dans le code Javascript de la page 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

Étape 7) Ajoutez le sous-fichier VB.Net suivant, que le Javascript recherchera ensuite lorsqu'il sera appelé:

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

Étape 8) Enfin, pour invoquer le rappel Javascript, ajoutez ce code VB.Net lorsqu'un bouton est enfoncé ou à l'endroit souhaité:

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

Étape 9) Si cela vous surprend que cela fonctionne, vous voudrez peut-être lire sur le Javascript " eval " fonction, utilisée à l’étape 6, c’est ce qui rend cela possible. Il faudra une chaîne pour déterminer si une variable existe avec ce nom et, si tel est le cas, renvoie la valeur de cette variable.

Vous pouvez toujours utiliser un " DocumentStream " ou " DocumentText " propriété. Pour travailler avec des documents HTML, je recommande un Pack d'agilité HTML .

Ce que vous voulez faire, c'est utiliser Page.RegisterStartupScript (clé, script) :

Voir ici pour plus de détails: http://msdn.microsoft.com /en-us/library/aa478975.aspx

En gros, vous construisez votre chaîne javascript, transmettez-la à cette méthode et attribuez-lui un identifiant unique (si vous essayez de l'enregistrer deux fois sur une page.)

EDIT: C’est ce que vous appelez le déclencheur heureux. N'hésitez pas à le descendre. :)

j'utilise ceci:

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

Si vous devez injecter un fichier entier, vous pouvez utiliser ceci:

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

N'oubliez pas d'importer System.IO pour pouvoir utiliser le StreamReader. J'espère que cela aide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top