[c#] WebBrowser 컨트롤에 Javascript를 삽입하는 방법은 무엇입니까?

나는 이것을 시도했다 :

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 및 scriptEl.InnerText 모두 오류가 발생합니다.

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)

DOM에 스크립트를 삽입하는 쉬운 방법이 있습니까?



답변

어떤 이유로 Richard의 솔루션이 내 쪽에서 작동하지 않았습니다 (insertAdjacentText가 예외로 실패했습니다). 그러나 이것은 작동하는 것 같습니다.

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

이 답변IHTMLScriptElement 은 프로젝트에 인터페이스 를 가져 오는 방법을 설명합니다 .


답변

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

(.NET 4 / Windows Forms 앱에서 테스트 됨)

편집 : 기능 세트의 케이스 문제를 수정했습니다.


답변

이 작업을 마치고 찾은 가장 쉬운 방법은 다음과 같습니다.

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

전역 JavaScript 함수 eval(str)가하는 일은 str에 작성된 모든 것을 구문 분석하고 실행하는 것입니다. 여기에서 w3schools ref를 확인 하십시오 .


답변

또한 .NET 4에서는 dynamic 키워드를 사용하면 더 쉽습니다.

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


답변

정말로 원하는 것이 자바 스크립트를 실행하는 것이라면 이것이 가장 쉬울 것입니다 (VB .Net).

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

나는 이것이 그것을 “주입”하지 않을 것이라고 생각하지만 그것이 당신이 추구하는 것이라면 당신의 함수를 실행할 것입니다. (문제를 지나치게 복잡하게 만든 경우를 대비하여.) 그리고 자바 스크립트에서 주입하는 방법을 알아낼 수 있다면이를 “foo”함수의 본문에 넣고 자바 스크립트가 자동으로 주입하도록하십시오.


답변

HTML 문서에 대한 관리되는 래퍼는 필요한 기능을 완전히 구현하지 않으므로 원하는 작업을 수행하려면 MSHTML API를 살펴 봐야합니다.

1) COM 참조 에서 “Microsoft HTML Object Library”라고하는 MSHTML에 대한 참조를 추가합니다 .

2) ‘using mshtml;’추가 네임 스페이스에.

3) 스크립트 요소의 IHTMLElement에 대한 참조를 가져옵니다.

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;

4) 첫 번째 매개 변수 값이 “afterBegin”인 insertAdjacentText 메소드를 호출합니다. 가능한 모든 값은 다음과 같습니다 .

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

5) 이제 scriptEl.InnerText 속성에서 코드를 볼 수 있습니다.

Hth, Richard


답변

허용되는 답변에 대한 후속 조치로 추가 형식 라이브러리를 포함 할 필요가없는 IHTMLScriptElement인터페이스 의 최소 ​​정의입니다 .

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

따라서 WebBrowser 컨트롤 파생 클래스 내부의 전체 코드는 다음과 같습니다.

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