Getting url and HTMl through a BHO, SetSite throws an exception

馋奶兔 提交于 2019-12-08 12:45:19

问题


I have followed the tutorial at: http://www.15seconds.com/issue/040331.htm for making a BHO, however i doesnt seem to work for me, i have the Observer code from the examble, where she creates the actual BHO, but when i try to typecast in my SetSite it stops, i suspect i get an exception.

This is my sample code, just stripped it all bare, so i get a messagebox instead.

[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");            
        }

My problem is in my SetSite method, how do i typecast to a browser of any sorts? If i run this sample as it is now, I only get the "GetSite" messagebox, if I remove the if sentence in the SetSite i also get the SetSite. Does anyone know how to do this?


回答1:


  1. (Non vital to the answer) You really shouldn't be writing a BHO in C#. Yes it can be done, but it isn't a good idea. Even with SxS in .NET 4; the cost of initializing the CLR for every tab opened is pretty high. (If you insist then you should at least be using .NET 4).

  2. The Get / Set site methods should return an int according to the documentation for IObjectWithSite. Your interface declaration is wrong.

  3. Your GetSite implementation should look something like this once you get the interface fixed up:

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

    In this case, _pUnkSite is the object that you were given at SetSite. So SetSite will look something like this:

    private object _pUnkSite;
    public int SetSite(object pUnkSite)
    {
        _pUnkSite = pUnkSite;
        //Cast pUnkSite to `IWebBrowser2` here and attach events.
        return 0;
    }
    

    Once you've finally gotten some of the boilerplate code taken care of, you can cast your pUnkSite to something like IWebBrowser2 to work with the DOM.

  4. <shamelessplug>I know that writing a C# BHO is a bad idea because I have done so. I have a boilerplate GitHub project here.</shamelessplug>



来源:https://stackoverflow.com/questions/8040904/getting-url-and-html-through-a-bho-setsite-throws-an-exception

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!