从Javascript调用C#BHO方法(仍不工作)
我严格按照答案,反复阅读谷歌的所有发现。不幸的是,大多数人都只是简单地复制和粘贴参考答案(包括“停止把头撞在墙上,去庆祝吧!”)这句话,它对我不起作用。。。所以在工作了半天之后,我真的要开始撞我的头了 我的简单错误: javascript windows.myExtension对象“未定义”,因此对其调用Foo会引发错误。请参阅下面的完整来源。属性集似乎在javascript端不可见 更多信息:从Javascript调用C#BHO方法(仍不工作),c#,internet-explorer,com,bho,C#,Internet Explorer,Com,Bho,我严格按照答案,反复阅读谷歌的所有发现。不幸的是,大多数人都只是简单地复制和粘贴参考答案(包括“停止把头撞在墙上,去庆祝吧!”)这句话,它对我不起作用。。。所以在工作了半天之后,我真的要开始撞我的头了 我的简单错误: javascript windows.myExtension对象“未定义”,因此对其调用Foo会引发错误。请参阅下面的完整来源。属性集似乎在javascript端不可见 更多信息: 我使用Debugger.Launch()语句方便地调试我的扩展,断点被命中,所有BHO扩展函数都被
- 我使用Debugger.Launch()语句方便地调试我的扩展,断点被命中,所有BHO扩展函数都被正确调用并运行
- 注释的备选方案(带有property.SetProperty)也不起作用,出现相同的错误: console.log(window.myExtension);//写“未定义”,为什么
- 使用VS 2010、Windows 7 x64、IE 9
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
console.log(window.myExtension); // Writes undefined why? It should be an object...
var result = window.myExtension.Foo("bar"); // Obviously throws and error if window.myExtension is undefined
</script>
<title></title>
</head>
<body>
</body>
</html>
IObjectWithSite.cs
using System;
using System.Runtime.InteropServices;
namespace IEExtensionTest
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
[PreserveSig]
int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site);
[PreserveSig]
int GetSite(ref Guid guid, out IntPtr ppvSite);
}
}
IExtension.cs
using System;
using System.Runtime.InteropServices;
namespace IEExtensionTest
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
[PreserveSig]
int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site);
[PreserveSig]
int GetSite(ref Guid guid, out IntPtr ppvSite);
}
}
生成后步骤的配置如下(并正常运行):
尝试使用窗口。外部.myExtension(); 外部是我记忆中保持你形体的物体。 此外,如果这不起作用-一定要尝试简单的事情,而不是相反的工作 这里有一个简单的表单,应该适合您:
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")] // Note full trust.
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public partial class BasicJSScriptableForm : Form
{
private void BasicJSScriptableForm _Load(object sender, EventArgs e){
this.WebBrowser1.Navigate("yourpage");
}
public string TestMethod(string input){
return string.Format("echo: {0}", input);
}
}
然后在页面中:
$(document).ready(function() {
alert(window.external.TestMethod("It will hopefully work."));
}
我有一个简单的解决办法。这是为我现在工作,所以我张贴在这里。如果我遇到任何问题,我会更新这篇文章 @Eli Gassert正确识别了问题。在
SetSite
函数中,我们将向DocumentComplete
事件添加一个处理程序。因此,当我们在$.ready()
中时,它不会执行
所以我所做的是将处理程序添加到BeforeScriptExecute事件。这是我的BHO.cs的相关部分
public int SetSite(object site)
{
this.site = site;
if(site != null)
{
webBrowser = (IWebBrowser2)site;
((DWebBrowserEvents2_Event)webBrowser).BeforeScriptExecute += S2_BeforeScriptExecute;
//((DWebBrowserEvents2_Event)webBrowser).DocumentComplete += S2_DocumentComplete;
}
else
{
((DWebBrowserEvents2_Event)webBrowser).BeforeScriptExecute -= S2_BeforeScriptExecute;
//((DWebBrowserEvents2_Event)webBrowser).DocumentComplete -= S2_DocumentComplete;
webBrowser = null;
}
return 0;
}
处理程序的签名不同,下面是处理程序的代码。这仍在BHO.cs中
private void S2_BeforeScriptExecute(object pDispWindow)
{
//if (pDisp != this.site) { return; }
dynamic window = webBrowser.Document.parentWindow;
IExpando windowEx = (IExpando)window;
windowEx.AddProperty("myprop");
window.myprop = this;
}
我刚刚粘贴了DocumentComplete
方法中的代码,并在顶部注释掉了条件
因此,我能够在jquery$.ready()
中看到myprop
。这解决了我眼前的问题,我正在继续我的代码
不用说,我的插件只提供从javascript调用的方法,不需要对文档内容做任何事情
我还不知道
pDispWindow
有什么用,不检查它是否为空会有什么影响,等等。只是尝试一下,但它看起来只是在文档完成时添加了myExtension
。试试这个黑客测试:setTimeout(function(){console.log(window.myExtension);},1000)代码>1秒后,它应该向控制台输出一些内容。此时,应该加载文档,并且您应该有您的答案。请在测试后报告。谢谢你的建议。我已经试过了,现在又试过了。这不是时间问题。window.myExtension在延迟的调用中仍然未定义:-(@Dalorzo请停止进行琐碎的编辑,例如在不需要的地方添加标记。我浏览了您的历史记录,您最近建议的大多数编辑都应该被拒绝。您这样做是不必要的,将旧问题推到了头版(通常是错误和/或不完整的)编辑。@Rob W我不认为这些内容微不足道。我希望这些内容能让更多的人看到一个未回答的问题。最后,旧问题应该得到回答。@g.pickardou嗨,你成功了,所以解决了这个问题吗?如果有人在新选项卡中打开链接或按刷新按钮两次以上,这个解决方案就不起作用了。
public int SetSite(object site)
{
this.site = site;
if(site != null)
{
webBrowser = (IWebBrowser2)site;
((DWebBrowserEvents2_Event)webBrowser).BeforeScriptExecute += S2_BeforeScriptExecute;
//((DWebBrowserEvents2_Event)webBrowser).DocumentComplete += S2_DocumentComplete;
}
else
{
((DWebBrowserEvents2_Event)webBrowser).BeforeScriptExecute -= S2_BeforeScriptExecute;
//((DWebBrowserEvents2_Event)webBrowser).DocumentComplete -= S2_DocumentComplete;
webBrowser = null;
}
return 0;
}
private void S2_BeforeScriptExecute(object pDispWindow)
{
//if (pDisp != this.site) { return; }
dynamic window = webBrowser.Document.parentWindow;
IExpando windowEx = (IExpando)window;
windowEx.AddProperty("myprop");
window.myprop = this;
}