C# Can';t调用在注入WebBrowser的代码中创建的JavaScript对象的方法';导航后的文档

C# Can';t调用在注入WebBrowser的代码中创建的JavaScript对象的方法';导航后的文档,c#,javascript,dom,browser,C#,Javascript,Dom,Browser,我还发现了一些类似的问题,但不完全是这样,而且解决方案并不能解决这个问题。我正在做一个类似iMacrosforInternetExplorer的项目。这是我的简化代码: public partial class Form1 : Form { public JSObject jsObject = new JSObject(); int uniqueNameEnsurer = 0; public Form1() { InitializeCompone

我还发现了一些类似的问题,但不完全是这样,而且解决方案并不能解决这个问题。我正在做一个类似iMacrosforInternetExplorer的项目。这是我的简化代码:

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;
}
所以,我要做的是,单击button1(调用
button1\u-click
),然后单击button2(调用
button2\u-click
),等待一秒钟加载,然后单击button3(调用
button3\u-click
)。
当我点击button3时,我会收到一个警告,说“hello”(这意味着该对象在导航后仍然存在),但紧接着,我会收到一个错误,说“无法从释放的脚本执行代码”。这可能是某种安全措施。我发现一些帖子在谈论我的问题,但没有一个能解决我的问题。我可以通过将我的
SomeFunc
创建为字符串,然后使用
eval
来解决这个问题,但这是一个糟糕的解决方案。如果我能对我的C#代码做些什么,让我保持JavaScript代码的原样(当然也可以正常工作),那就太酷了。如果没有,最好的解决方法是什么,这样我可以在导航后调用
SomeFunc

这里有一些事情我不太明白。首先,我不指望在调用导航后脚本会出现在那里。一旦你导航,我认为你应该重新注入你想要的所有脚本

第二,我不明白“MyObject”的定义是什么?我在您的脚本中看到了“newmyobject();”,但我在任何地方都没有看到定义MyObject函数,因此没有定义SomeFunc()并不奇怪。假设样本不完整


最后,您应该研究在JSObject上实现IReflect和IExpando。它可能会解决你所有的问题。

好吧,很显然,仅仅用C#是不可能做到我想做的事情的。我需要在JavaScript中实现某种对象序列化和反序列化系统,在导航之前序列化
UserData
,在导航之后反序列化

我想我可以通过将对象序列化为字符串来解决这个问题,但是该方法也需要序列化,不确定这样做的最佳方式是什么。MyObject是在第一次调用JavaScript代码时定义的,并且创建了MyObject的一个实例并传递回我的C#app,然后传递回第二次JavaScript调用。我不指望脚本在调用导航后出现。他们不会的。但我希望对象的实例在导航之后以某种方式保持不变。