从Javascript调用C#BHO方法

fix*_*int 11 c# com internet-explorer bho c#-4.0

我正试图弄清楚如何在页面内的Javascript中调用我的BHO对象中的C#方法.我在C++/ATL/Com中找到了很多关于如何做的页面,例如:

浏览器帮助程序对象和脚本选项

从Javascript调用BHO方法?

我试图在C#中正确地实现它,但是我无法让它工作,可能是因为我有一些明显的COM问题,我并不完全理解.

我正在使用C#4.0.

以下是代码的相关部分:

using SHDocVw;
using mshtml;
using System.Runtime.InteropServices;

[ComVisible(true),
 Guid("300736C4-DCDA-4DB0-90AD-4510A12EBBC6"),
 ClassInterface(ClassInterfaceType.None),
 ProgId("My Extension")]
public class BrowserHelperObject : IObjectWithSite
{
    const int DISPATCH_PROPERTYPUT = 4;
    const int FDEX_NAME_ENSURE = 2;
    const uint LOCALE_USER_DEFAULT = 0x0400;

    WebBrowser browser;

    ...
    public void OnDocumentComplete(dynamic frame, ref dynamic url)
    {
        ...
        var window = browser.Document.parentWindow;

        int pid = 0;
        window.GetDispId("myExtension", FDEX_NAME_ENSURE, ref pid);

        System.Runtime.InteropServices.ComTypes.DISPPARAMS dispParms = new System.Runtime.InteropServices.ComTypes.DISPPARAMS();
        dispParms.cArgs = 1;
        dispParms.cNamedArgs = 0;
        dispParms.rgvarg = ???;
        dispParms.rgdispidNamedArgs = IntPtr.Zero;
        System.Runtime.InteropServices.ComTypes.EXCEPINFO einfo = new System.Runtime.InteropServices.ComTypes.EXCEPINFO();
        window.Invoke(pid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ref dispParms, this, ref einfo);            
        ...
    }
Run Code Online (Sandbox Code Playgroud)

fix*_*int 24

我讨厌回答我自己的问题,但我真的觉得社区应该知道答案,因为C#4.0简短,美观,很多人似乎都有这个问题.

确保正确公开浏览器帮助程序对象:

[ComVisible(true),
 Guid("DA8EA345-02AE-434E-82E9-448E3DB7629E"),
 ClassInterface(ClassInterfaceType.None), ProgId("MyExtension"),
 ComDefaultInterface(typeof(IExtension))]
public class BrowserHelperObject : IObjectWithSite, IExtension
{
    ...
    public int Foo(string s) { ... }
    ...
    public void OnDocumentComplete(dynamic frame, ref dynamic url)
    {
        ...
        dynamic window = browser.Document.parentWindow;
        IExpando windowEx = (IExpando)window;
        windowEx.AddProperty("myExtension");
        window.myExtension = this;
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

您需要为扩展程序定义:

[ComVisible(true),
 Guid("4C1D2E51-018B-4A7C-8A07-618452573E42"),
 InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IExtension
{
    [DispId(1)]
    int Foo(string s);
    ...
}
Run Code Online (Sandbox Code Playgroud)

您可以在javascript中访问您的浏览器帮助程序对象:

var result = window.myExtension.Foo("bar");
Run Code Online (Sandbox Code Playgroud)

要不就

var result = myExtension.Foo("bar");
Run Code Online (Sandbox Code Playgroud)

而已.别再撞到墙上去庆祝吧!

  • 不要后悔回答你自己的问题.因为,i)人们寻找答案而不是回答的人,ii)你发布了一个问题并且你能够回答它意味着你已经处理了它. '认真的好事..恭喜...... (6认同)
  • 可能你没有在你的实现类中包含ComDefaultInterface(typeof(IExtension)),这就是为什么它不工作 (2认同)