C# Can';t调用在注入WebBrowser的代码中创建的JavaScript对象的方法';导航后的文档
我还发现了一些类似的问题,但不完全是这样,而且解决方案并不能解决这个问题。我正在做一个类似iMacrosforInternetExplorer的项目。这是我的简化代码: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
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调用。我不指望脚本在调用导航后出现。他们不会的。但我希望对象的实例在导航之后以某种方式保持不变。