C# 通过BHO获取url和HTMl时,SetSite会引发异常

C# 通过BHO获取url和HTMl时,SetSite会引发异常,c#,com,interop,bho,C#,Com,Interop,Bho,我遵循了以下教程:为了制作BHO,但是我似乎不适合自己,我有examble中的Observer代码,她在那里创建了实际的BHO,但是当我尝试在我的设置位置进行打字时,它停止了,我怀疑我得到了一个例外 这是我的示例代码,只是将其全部剥离,所以我得到了一个messagebox [ClassInterfaceAttribute(ClassInterfaceType.None)] [GuidAttribute("0CD00297-9A19-4698-AEF1-682FBE9FE88D")]

我遵循了以下教程:为了制作BHO,但是我似乎不适合自己,我有examble中的Observer代码,她在那里创建了实际的BHO,但是当我尝试在我的设置位置进行打字时,它停止了,我怀疑我得到了一个例外

这是我的示例代码,只是将其全部剥离,所以我得到了一个messagebox

[ClassInterfaceAttribute(ClassInterfaceType.None)]
    [GuidAttribute("0CD00297-9A19-4698-AEF1-682FBE9FE88D")]
    [ProgIdAttribute("Observer.BrowserMonitor")]
    public class BrowserMonitor: IObserver, IObjectWithSite
    {

        // HRESULT values used
        const int E_FAIL = unchecked((int)0x80004005);
        const int E_NOINTERFACE = unchecked((int)0x80004002);

        public BrowserMonitor()
        {

        }


        protected SHDocVw.IWebBrowser2 m_pIWebBrowser2; // the browser class object

        public void SetSite(object pUnkSite)
        {
            System.Windows.Forms.MessageBox.Show(pUnkSite.ToString());
            if (pUnkSite != null)
            {
                m_pIWebBrowser2 = pUnkSite as SHDocVw.IWebBrowser2;
            }
        }

        public void GetSite(ref System.Guid riid, out object ppvSite)
        {            
            System.Windows.Forms.MessageBox.Show("GetSite");
            ppvSite = null;
        }

        protected void DocumentComplete(object pDisp, ref object URL)
        {            
            System.Windows.Forms.MessageBox.Show("DocumentComplete");

        }

        protected bool ServiceEnabled()
        {
            return true;
        }

        protected void Release()
        {
            System.Windows.Forms.MessageBox.Show("Release");
        }

        protected void BeforeNavigate2(object pDisp, ref object url, ref object Flags, ref object TargetFrameName, 
            ref object PostData, ref object Headers, ref bool Cancel)
        {
            System.Windows.Forms.MessageBox.Show("BeforeNavigate2");
        }

        protected void OnQuit() 
        {
            try
            {
                System.Windows.Forms.MessageBox.Show("OnQuit");
            }
            catch{}
        }

        protected void NavigateComplete2(object pDisp, ref object URL)
        {
            System.Windows.Forms.MessageBox.Show("NavigationComplete2");            
        }
我的问题是在我的SetSite方法中,我如何向任何类型的浏览器进行类型转换?如果我像现在这样运行这个示例,我只会得到“GetSite”消息框,如果我删除SetSite中的If语句,我也会得到SetSite。有人知道怎么做吗

  • (对答案不重要)你真的不应该用C#写BHO。是的,这是可以做到的,但这不是一个好主意。即使是.NET4中的SxS;为每个打开的选项卡初始化CLR的成本相当高。(如果您坚持,那么您至少应该使用.NET4)

  • 根据的文档,Get/Set site方法应该返回int。您的接口声明是错误的

  • 一旦修复了接口,您的
    GetSite
    实现应该是这样的:

    public int GetSite(ref Guid riid, out IntPtr ppvSite)
    {
        var pUnk = Marshal.GetIUnknownForObject(_pUnkSite);
        try
        {
            return Marshal.QueryInterface(pUnk, ref riid, out ppvSite);
        }
        finally
        {
            Marshal.Release(pUnk);
        }
    }
    
    在本例中,
    \u pUnkSite
    是在
    SetSite
    中提供给您的对象。因此,
    SetSite
    将如下所示:

    private object _pUnkSite;
    public int SetSite(object pUnkSite)
    {
        _pUnkSite = pUnkSite;
        //Cast pUnkSite to `IWebBrowser2` here and attach events.
        return 0;
    }
    
    一旦您最终处理了一些样板代码,您就可以将
    朋克站点
    转换为类似于
    IWebBrowser2
    的内容来使用DOM

  • 我知道写C#BHO是个坏主意。我有一个样板GitHub项目


  • 如果我删除“如果”,只留下messagebox,它将显示messagebox。如果我把“如果”结构留在那里,我甚至不会得到messagebox弹出窗口,但它不是设置站点吗?我正在寻找一个webbrowser中的类型转换,以便连接到导航事件。在我阅读tuts时,加载GetSite后会调用它,以便在需要时发布?@H4mm3rHead您的C#接口需要与COM IDL的定义匹配。NET将在排列不正确的情况下发生封送错误。只需将这两个方法都更改为int,并使实现返回0(零)-这导致我的IExplorer挂起,但没有任何响应,在此更改之前,我收到了我的MessageBox新版本:查看了你的tut,我在界面中跟踪的didnt user[PreserveSig],现在我做了,并更改了返回int的方法,一切都正常(使用返回类型),我得到了我的messagebox——仍然没有类型转换yet@H4mm3rHead
    GetSite
    不应返回零。请参阅我的更新代码示例。