从Javascript调用C#BHO方法(仍不工作)

从Javascript调用C#BHO方法(仍不工作),c#,internet-explorer,com,bho,C#,Internet Explorer,Com,Bho,我严格按照答案,反复阅读谷歌的所有发现。不幸的是,大多数人都只是简单地复制和粘贴参考答案(包括“停止把头撞在墙上,去庆祝吧!”)这句话,它对我不起作用。。。所以在工作了半天之后,我真的要开始撞我的头了 我的简单错误: javascript windows.myExtension对象“未定义”,因此对其调用Foo会引发错误。请参阅下面的完整来源。属性集似乎在javascript端不可见 更多信息: 我使用Debugger.Launch()语句方便地调试我的扩展,断点被命中,所有BHO扩展函数都被

我严格按照答案,反复阅读谷歌的所有发现。不幸的是,大多数人都只是简单地复制和粘贴参考答案(包括“停止把头撞在墙上,去庆祝吧!”)这句话,它对我不起作用。。。所以在工作了半天之后,我真的要开始撞我的头了

我的简单错误: javascript windows.myExtension对象“未定义”,因此对其调用Foo会引发错误。请参阅下面的完整来源。属性集似乎在javascript端不可见

更多信息:

  • 我使用Debugger.Launch()语句方便地调试我的扩展,断点被命中,所有BHO扩展函数都被正确调用并运行
  • 注释的备选方案(带有property.SetProperty)也不起作用,出现相同的错误:

    console.log(window.myExtension);//写“未定义”,为什么

  • 使用VS 2010、Windows 7 x64、IE 9

请让我帮你运行这个。。。 提前Thx

简单测试页面:

<!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;
    }