Frage

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

scriptEl.InnerHtml und scriptEl.InnerText geben beide 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 einzuschleusen?

War es hilfreich?

Lösung

Aus irgendeinem Grund funktionierte Richards Lösung an meinem Ende nicht (InsertAdjaCentText ist mit 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 man das bekommt IHTMLScriptElement Schnittstelle in Ihr Projekt.

Andere Tipps

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 festem Fall im Funktionssatz.

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

Welche globale JavaScript -Funktion eval(str) TUE ist analysiert und führt alles aus, was in Str. Prüfen W3Schools Ref hier.

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

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

Wenn Sie nur JavaScript ausführen möchten, wäre 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 überkompliziert haben.) Und wenn Sie herausfinden können, wie Sie JavaScript injizieren können, geben Sie das in den Körper der Funktion "foo" und lassen Sie das JavaScript die Injektion für Sie machen.

Der verwaltete Wrapper für das HTML -Dokument implementiert die von Ihnen benötigte Funktionalität nicht vollständig. Daher müssen Sie in die MSHTML -API eintauchen, um das zu erreichen, was Sie wollen:

1) Fügen Sie eine Referenz zu MSHTML hinzu, die wahrscheinlich "Microsoft HTML -Objektbibliothek" unter bezeichnet wird Com Verweise.

2) add 'mit MSHTML;' in Ihren Namespaces.

3) Erhalten Sie einen Hinweis auf das iHtmlelement Ihres Skriptelements:

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;

4) Rufen Sie die InsertAdjaCentText -Methode mit dem ersten Parameterwert von "Afterbei" auf. Alle möglichen Werte sind aufgeführt hier:

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

5) Jetzt können Sie den Code in der Eigenschaft script.InNeText sehen.

HTH, Richard

Als Follow-up an die Akzeptierte Antwort, Dies ist eine minimale Definition der IHTMLScriptElement Schnittstelle Dies ist nicht erforderlich, um zusätzliche Typbibliotheken einzuschließen:

[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 der Webbrowser abgeleiteten Klasse würde also aussehen wie:

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

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

Ich glaube, die einfachste Methode, um JavaScript in ein HTML -Dokument für Webbrowser -Steuerung aus C# zu injizieren, besteht darin, die "execstrip" -Methode mit dem Code als Argument aufzurufen.

In diesem Beispiel wird der JavaScript -Code in Global Scope injiziert 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, injizieren Sie Funktionen und rufen Sie sie an:

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 -Formulare und WPF -Webbrowser -Steuerelemente.

Diese Lösung ist kein Cross -Browser, da "execscript" nur in IE und Chrom definiert ist. Die Frage ist jedoch die Microsoft -Webbrowser -Steuerelemente und der einzige, der unterstützt wird.

Erstellen Sie ein Funktionsobjekt mit dem neuen Schlüsselwort, um einen gültigen Cross -Browser -Methode zum Injektion von JavaScript -Code zu erstellen. Dieses Beispiel erstellt eine anonyme Funktion mit injiziertem Code und führt ihn aus (JavaScript implementiert Verschlüsse und die Funktion hat Zugriff auf den globalen Raum ohne lokale variable Verschmutzung).

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

Ich habe das verwendet: 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 das Ergebnis ausführen und erzielen 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 aus einer in ein WebBrowser-Steuerelement geladenen Seite abzurufen.

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

Schritt 2) Als nächstes fügen Sie diesen VB.Net-Code zu Ihrem 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 = Me

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) Um schließlich den Javascript-Rückruf aufzurufen, fügen Sie diesen VB.Net-Code hinzu, wenn eine Schaltfläche 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, können Sie sich über die in Schritt 6 verwendete Javascript-Funktion „eval“ informieren, die dies ermöglicht.Es nimmt eine Zeichenfolge und ermittelt, ob eine Variable mit diesem Namen existiert. Wenn ja, wird der Wert dieser Variablen zurückgegeben.

Sie können jederzeit eine Eigenschaft "documentStream" oder "documentText" verwenden. Für die Arbeit mit HTML -Dokumenten empfehle ich a HTML Agility Pack.

Sie möchten Seite verwenden.

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

Was Sie im Grunde genommen tun, ist Ihre JavaScript -Zeichenfolge zu erstellen, sie an diese Methode weiterzugeben und ihm eine eindeutige ID zu geben (falls Sie versuchen, sie zweimal auf einer Seite zu registrieren).

Bearbeiten: Das nennst du Trigger glücklich. Fühlen Sie sich frei, es abzufinden. :)

ich benutze das:

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

Wenn Sie eine ganze Datei injizieren 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 zu importieren System.IO Um die zu verwenden StreamReader. Ich hoffe das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top