获取URL和HTML通过BHO,SetSite抛出一个异常 [英] Getting url and HTMl through a BHO, SetSite throws an exception
问题描述
我也跟着教程在: 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。有谁知道如何做到这一点?
-
(非至关重要的答案)你真的不应该写一个BHO在C#。是的,这是可以做到的,但它不是一个好主意。即使在.NET 4的SxS;初始化CLR为每开卡的成本是相当高的。 (如果你坚持,那么你至少应该使用.NET 4)。
-
get / set方法现场方法应根据为文档返回一个int < A HREF =http://msdn.microsoft.com/en-us/library/aa768220%28v=vs.85%29.aspx相对=nofollow>
的IObjectWithSite
。你的接口声明是错误的。 -
您
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工作。 -
< 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?
(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).
The Get / Set site methods should return an int according to the documentation for
IObjectWithSite
. Your interface declaration is wrong.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 atSetSite
. SoSetSite
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 likeIWebBrowser2
to work with the DOM.<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屋!