1

我正在尝试将我为 Google Chrome 编写的内容脚本转换为 IE 插件,主要使用此答案中的代码。

我需要注入一个样式表,并且我找到了一种使用 Javascript的方法。我想我也许可以使用 C# 来做同样的事情。这是我的代码:

[ComVisible(true)]
[Guid(/* replaced */)]
[ClassInterface(ClassInterfaceType.None)]
public class SimpleBHO: IObjectWithSite
{
    private WebBrowser webBrowser;

    void webBrowser_DocumentComplete(object pDisp, ref object URL)
    {
        var document2 = webBrowser.Document as IHTMLDocument2;
        var document3 = webBrowser.Document as IHTMLDocument3;

        // trying to add a '<style>' element to the header. this does not work.
        var style = document2.createElement("style");
        style.innerHTML = ".foo { background-color: red; }";// this line is the culprit!
        style.setAttribute("type", "text/css");
        var headCollection = document3.getElementsByTagName("head");
        var head = headCollection.item(0, 0) as IHTMLDOMNode;
        var result = head.appendChild(style as IHTMLDOMNode);

        // trying to repace an element in the body. this part works if
        // adding style succeeds.
        var journalCollection = document3.getElementsByName("elem_id");
        var journal = journalCollection.item(0, 0) as IHTMLElement;
        journal.innerHTML = "<div class=\"foo\">Replaced!</div>";

        // trying to execute some JavaScript. this part works as well if
        // adding style succeeds.
        document2.parentWindow.execScript("alert('Hi!')");
    }

    int IObjectWithSite.SetSite(object site)
    {
        if (site != null)
        {
            webBrowser = (WebBrowser)site;
            webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(webBrowser_DocumentComplete);
        }
        else
        {
            webBrowser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(webBrowser_DocumentComplete);
            webBrowser = null;
        }
        return 0;
    }

    /* some code (e.g.: IObjectWithSite.SetSite) omitted to improve clarity */
}

如果我只是注释掉以下行......

style.innerHTML = ".foo { background-color: red; }";

...其余代码完美执行(#elem_id替换元素并执行我注入的 JavaScript)。

尝试注入样式表时我做错了什么?这甚至可能吗?

编辑:我发现我试图注入 CSS 的站点请求文档模式 5,并且当兼容性视图被禁用时,我的代码运行良好。但是,即使启用了兼容性视图,我该如何让它工作呢?

4

1 回答 1

1

经过大量试验,我发现注入样式表的唯一故障安全方法是使用 JavaScript 注入样式表,使用IHTMLWindow2.execScript().

我使用了以下 JavaScript:

var style = document.createElement('style');
document.getElementsByTagName('head')[0].appendChild(style);
var sheet = style.styleSheet || style.sheet;

if (sheet.insertRule) {
    sheet.insertRule('.foo { background-color: red; }', 0);
} else if (sheet.addRule) {
    sheet.addRule('.foo', 'background-color: red;', 0);
}

上面的 JavaScript 以下列方式执行:

// This code is written inside a BHO written in C#
var document2 = webBrowser.Document as IHTMLDocument2;
document2.parentWindow.execScript(@"
    /* Here, we have the same JavaScript mentioned above */
    var style = docu....
    ...
    }");
document2.parentWindow.execScript("alert('Hi!')");
于 2015-04-23T17:39:54.807 回答