获取URL和HTML通过BHO,SetSite抛出一个异常 [英] Getting url and HTMl through a BHO, SetSite throws an exception

查看:235
本文介绍了获取URL和HTML通过BHO,SetSite抛出一个异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我也跟着教程在: http://www.15seconds.com/issue/040331的.htm 制作一个BHO,但是我似乎没有为我工作,我从examble,在那里她创建的实际BHO观察代码,但是当我尝试在我的SetSite类型转换到停止,我怀疑我得到一个异常。



这是我的示例代码,就剥夺了一切光秃秃的,所以我得到一个消息来代替。

  [ClassInterfaceAttribute(ClassInterfaceType.None)
[GuidAttribute(0CD00297-9A19-4698-AEF1-682FBE9FE88D )
[ProgIdAttribute(Observer.BrowserMonitor)]
公共类BrowserMonitor:b $ b {使用IObserver,接口IObjectWithSite $

// HRESULT值
常量INT E_FAIL =选中((INT)0x80004005的);
const int的E_NOINTERFACE =选中((INT)0x80004002);

公共BrowserMonitor()
{

}


保护SHDocVw.IWebBrowser2 m_pIWebBrowser2; //浏览器类对象

公共无效SetSite(对象pUnkSite)
{
System.Windows.Forms.MessageBox.Show(pUnkSite.ToString());
如果(pUnkSite!= NULL)
{
m_pIWebBrowser2 = pUnkSite为SHDocVw.IWebBrowser2;
}
}

公共无效GetSite(REF的System.Guid RIID,out对象ppvSite)
{
System.Windows.Forms.MessageBox.Show (GetSite);
ppvSite = NULL;
}

保护无效的DocumentComplete(对象pDisp,参考目标URL)
{
System.Windows.Forms.MessageBox.Show(的DocumentComplete);

}

保护布尔ServiceEnabled()
{
返回真;
}

保护无效发行()
{
System.Windows.Forms.MessageBox.Show(发行);
}

保护无效在BeforeNavigate2(对象pDisp,参考目标URL,参考对象旗帜,裁判的对象TargetFrameName,
Ref对象的PostData,参考对象接头,REF布尔取消)
{
System.Windows.Forms.MessageBox.Show(在BeforeNavigate2);
}

保护无效OnQuit()
{

{
System.Windows.Forms.MessageBox.Show(OnQuit );
}
赶上{}
}

保护无效NavigateComplete2(对象pDisp,参考目标URL)
{
System.Windows.Forms的.MessageBox.Show(NavigationComplete2);
}



我的问题是在我的SetSite方法,我怎么类型强制转换的浏览器任何为哪般?如果我运行这个样本,因为它是现在,我只得到了GetSite消息框,如果我删除if语句在SetSite我也得到了SetSite。有谁知道如何做到这一点?


解决方案

  1. (非至关重要的答案)你真的不应该写一个BHO在C#。是的,这是可以做到的,但它不是一个好主意。即使在.NET 4的SxS;初始化CLR为每开卡的成本是相当高的。 (如果你坚持,那么你至少应该使用.NET 4)。


  2. get / set方法现场方法应根据为文档返回一个int < A HREF =http://msdn.microsoft.com/en-us/library/aa768220%28v=vs.85%29.aspx相对=nofollow> 的IObjectWithSite 。你的接口声明是错误的。


  3. GetSite 的实施应该是这样的东西,一旦你得到了接口搞掂:

     公众诠释GetSite(REF的Guid RIID,出的IntPtr ppvSite)
    {
    变种朋克= Marshal.GetIUnknownForObject(_pUnkSite);

    {
    返回Marshal.QueryInterface(朋克,REF RIID,出ppvSite);
    }
    终于
    {
    Marshal.Release(朋克);
    }
    }

    在这种情况下, _pUnkSite 是你在 SetSite 给出的对象。因此, SetSite 会是这个样子:

     私有对象_pUnkSite; 
    公众诠释SetSite(对象pUnkSite)
    {
    _pUnkSite = pUnkSite;
    //铸造pUnkSite为`这里IWebBrowser2`和附加事件。
    返回0;
    }

    在你终于得到了一些,你照顾的样板代码可以施展你的 pUnkSite 来像的IWebBrowser2 与DOM工作。


  4. < shamelessplug I标记知道写一个C#BHO是一个坏主意的,因为我已经这样做了。我有一个样板项目GitHub的这里< / shamelessplug>



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. (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>

这篇关于获取URL和HTML通过BHO,SetSite抛出一个异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆