Невозможно вызвать метод объекта JavaScript, созданного в коде, внедренном в документ WebBrowser после навигации - PullRequest
1 голос
/ 15 февраля 2011

Я нашел несколько других вопросов, подобных этому, но не совсем, и с решениями, которые не решают эту конкретную проблему.Я работаю над проектом, похожим на iMacros для Internet Explorer.Это мой упрощенный код:

public partial class Form1 : Form
{
    public JSObject jsObject = new JSObject();
    int uniqueNameEnsurer = 0;

    public Form1()
    {
        InitializeComponent();
        webBrowser1.Navigate("www.google.com");
    }

    private void InvokeCode(string functionCode)
    {
        HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
        HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
        IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
        element.text = "function MyInjectedFunction" + uniqueNameEnsurer + "(Param){" + functionCode + "}";
        head.AppendChild(scriptEl);
        webBrowser1.Document.InvokeScript("MyInjectedFunction" + uniqueNameEnsurer, new object[] { jsObject });
        uniqueNameEnsurer++;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        InvokeCode(@"
            function MyObject()
            {
                this.Something = 'hello';
                this.SomeFunc = function(){
                    alert('in SomeFunc!!!');
                }
            }

            Param.UserData = new MyObject();
        ");
    }

    private void button2_Click(object sender, EventArgs e)
    {
        webBrowser1.Navigate("www.bing.com");
    }

    private void button3_Click(object sender, EventArgs e)
    {
        InvokeCode(@"
            alert(Param.UserData.Something);
            Param.UserData.SomeFunc();
        ");
    }
}

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class JSObject
{
    public object UserData;
}

Итак, что я делаю, нажмите кнопку 1 (которая вызывает button1_Click), затем кнопку 2 (которая вызывает button2_Click), подождите секунду, чтобы загрузить, а затемнажмите кнопку 3 (которая вызывает button3_Click).Когда я нажимаю кнопку 3, я получаю предупреждение «привет» (что означает, что объект как-то сохраняется после навигации), но сразу после этого я получаю сообщение об ошибке «Не удается выполнить код из освобожденного скрипта».Это, наверное, какая-то вещь безопасности.Я нашел несколько сообщений, о которых я говорил, но ни одна из них не решила мою проблему.Я могу обойтись, создав SomeFunc в виде строки, а затем используя eval, но это неприятное решение.Если бы я мог что-то сделать со своим кодом на C #, который позволил бы мне сохранить код JavaScript таким, какой он есть (и работает, конечно), это было бы очень круто.Если нет, что лучше всего обойти, чтобы я мог позвонить SomeFunc после навигации?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2011

ОК, по-видимому, просто НЕ возможно сделать то, что я пытаюсь сделать только с C #. Мне нужно будет внедрить какую-то систему сериализации и десериализации объектов в JavaScript и сериализовать UserData перед навигацией и десериализовать ее после навигации.

0 голосов
/ 20 февраля 2011

Здесь происходит несколько вещей, которые я не совсем понимаю. Во-первых, я бы не стал рассчитывать на наличие сценариев после вызова Navigate. Как только вы переместитесь, я думаю, вы должны повторно внедрить все свои сценарии, которые вы хотите.

Во-вторых, я не вижу, где определяется "MyObject"? Я вижу "новый MyObject ();" в вашем скрипте нет, но я не вижу нигде определенной функции MyObject, поэтому меня не удивляет, что ваш SomeFunc () не определен. Предполагая, что образец просто неполный.

И, наконец, вы должны изучить реализацию IReflect и IExpando на вашем JSObject. Это может решить все ваши проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...