it-swarm.com.de

Wie man Javascript in das WebBrowser-Steuerelement einfügt?

Ich habe es versucht:

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

sowohl scriptEl.InnerHtml als auch scriptEl.InnerText geben Fehler aus:

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)

Gibt es eine einfache Möglichkeit, ein Skript in den Dom einzufügen?

79
jsight

Aus irgendeinem Grund hat Richards Lösung bei mir nicht funktioniert (insertAdjacentText ist mit einer Ausnahme fehlgeschlagen). Dies scheint jedoch zu funktionieren:

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

Diese Antwort erklärt, wie Sie die Schnittstelle IHTMLScriptElement in Ihr Projekt integrieren.

98
Atanas Korchev
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");

(getestet in .NET 4/Windows Forms App)

Bearbeiten: Problem mit Groß- und Kleinschreibung im Funktionssatz behoben.

46
typpo

Hier ist der einfachste Weg, den ich gefunden habe, nachdem ich daran gearbeitet habe:

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

Die globale JavaScript-Funktion eval(str) analysiert und führt alles aus, was in str geschrieben ist. Check w3schools ref hier .

29
Ilya Rosikhin

In .NET 4 ist dies sogar noch einfacher, wenn Sie das Schlüsselwort dynamic verwenden:

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

Wenn Sie nur Javascript ausführen möchten, ist dies am einfachsten (VB .Net):

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

Ich denke, das würde es nicht "injizieren", aber es wird Ihre Funktion ausführen, wenn Sie danach suchen. (Nur für den Fall, dass Sie das Problem zu kompliziert haben.) Und wenn Sie herausfinden können, wie Sie in Javascript injizieren, setzen Sie dies in den Text der Funktion "foo" und lassen Sie das Javascript die Injektion für Sie tun.

17
Eyal

Der verwaltete Wrapper für das HTML-Dokument implementiert die von Ihnen benötigten Funktionen nicht vollständig. Daher müssen Sie in die MSHTML-API eintauchen, um die gewünschten Ergebnisse zu erzielen:

1) Fügen Sie einen Verweis auf MSHTML hinzu, der normalerweise unter [~ # ~] com [~ # ~] als "Microsoft HTML Object Library" bezeichnet wird .

2) Fügen Sie 'using mshtml;' zu Ihren Namespaces.

3) Holen Sie sich einen Verweis auf das IHTMLElement Ihres Skriptelements:

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;

4) Rufen Sie die insertAdjacentText-Methode mit dem ersten Parameterwert von "afterBegin" auf. Alle möglichen Werte sind aufgelistet hier :

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

5) Jetzt können Sie den Code in der Eigenschaft scriptEl.InnerText sehen.

Hth, Richard

10
ZeroBugBounce

Im Anschluss an akzeptierte Antwort ist dies eine Minimaldefinition der IHTMLScriptElement -Schnittstelle , die keine zusätzlichen Typbibliotheken enthalten muss:

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

Ein vollständiger Code in einer von einem WebBrowser-Steuerelement abgeleiteten Klasse sieht also folgendermaßen aus:

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

dies ist eine Lösung mit 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);
7
Camilo Sanchez

Ich glaube, die einfachste Methode, um Javascript in ein WebBrowser-Steuerelement-HTML-Dokument aus c # einzufügen, besteht darin, die Methode "execStrip" mit dem Code aufzurufen, der als Argument eingefügt werden soll.

In diesem Beispiel wird der Javascript-Code im globalen Bereich eingefügt und ausgeführt:

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

Wenn Sie die Ausführung verzögern möchten, fügen Sie Funktionen ein und rufen Sie sie anschließend auf:

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

Dies gilt für Windows Forms- und WPF-WebBrowser-Steuerelemente.

Diese Lösung ist nicht browserübergreifend, da "execScript" nur in IE und Chrome definiert ist. Die Frage bezieht sich jedoch auf Microsoft WebBrowser-Steuerelemente und IE ist die einzige unterstützt.

Erstellen Sie für eine gültige browserübergreifende Methode zum Einfügen von JavaScript-Code ein Function-Objekt mit dem neuen Schlüsselwort. In diesem Beispiel wird eine anonyme Funktion mit injiziertem Code erstellt und ausgeführt (Javascript implementiert Closures und die Funktion hat Zugriff auf den globalen Speicherplatz ohne Verschmutzung durch lokale Variablen).

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

Natürlich können Sie die Ausführung verzögern:

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

Ich hoffe es hilft

7
Santiago

Ich habe das benutzt: D

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

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

Dann können Sie ausführen und das Ergebnis erhalten mit:

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

Ich hoffe hilfreich zu sein

Hier ist ein VB.Net-Beispiel, wenn Sie versuchen, den Wert einer Variablen von einer Seite abzurufen, die in ein WebBrowser-Steuerelement geladen wurde.

Schritt 1) ​​Fügen Sie in Ihrem Projekt einen COM-Verweis zur Microsoft HTML-Objektbibliothek hinzu

Schritt 2) Fügen Sie als Nächstes diesen VB.Net-Code zu Form1 hinzu, um die mshtml-Bibliothek zu importieren:
Importiert mshtml

Schritt 3) Fügen Sie diesen VB.Net-Code über Ihrer Zeile "Public Class Form1" hinzu:
<System.Runtime.InteropServices.ComVisibleAttribute (True)>

Schritt 4) Fügen Sie Ihrem Projekt ein WebBrowser-Steuerelement hinzu

Schritt 5) Fügen Sie diesen VB.Net-Code zu Ihrer Form1_Load-Funktion hinzu:
WebBrowser1.ObjectForScripting = Ich

Schritt 6) Fügen Sie dieses VB.Net-Sub hinzu, das eine Funktion "CallbackGetVar" in das Javascript der Webseite einfügt:

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

Schritt 7) Fügen Sie das folgende VB.Net-Sub hinzu, nach dem das Javascript dann sucht, wenn es aufgerufen wird:

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

Schritt 8) Fügen Sie zum Aufrufen des Javascript-Rückrufs diesen VB.Net-Code hinzu, wenn eine Taste gedrückt wird, oder wo immer Sie möchten:

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

Schritt 9) Wenn Sie überrascht sind, dass dies funktioniert, sollten Sie sich über die in Schritt 6 verwendete Javascript-Funktion "eval" informieren, die dies ermöglicht. Es wird eine Zeichenfolge verwendet, um festzustellen, ob eine Variable mit diesem Namen vorhanden ist, und in diesem Fall den Wert dieser Variablen zurückgeben.

2
sh0ber

Sie können immer eine "DocumentStream" - oder "DocumentText" -Eigenschaft verwenden. Für die Arbeit mit HTML-Dokumenten empfehle ich ein HTML Agility Pack .

1
TcKs

ich benutze das:

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

Wenn Sie eine ganze Datei einfügen müssen, können Sie dies verwenden:

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

Denken Sie daran, System.IO Zu importieren, um StreamReader zu verwenden. Ich hoffe das hilft.

0
pablo

Was Sie tun möchten, ist die Verwendung von Page.RegisterStartupScript (Schlüssel, Skript):

Weitere Informationen finden Sie hier: http://msdn.Microsoft.com/en-us/library/aa478975.aspx

Im Grunde bauen Sie Ihren Javascript-String auf, übergeben ihn an diese Methode und geben ihm eine eindeutige ID (falls Sie versuchen, ihn zweimal auf einer Seite zu registrieren).

EDIT: Das nennst du Trigger gerne. Fühlen Sie sich frei, es niederzuschlagen. :)

0
mattlant