返回首页

简介
本文包含Microsoft.mshtml.dll和Shdocvw.dll的讨论。背景
我在C#中的IE浏览器的BHO的工作。起初我不知道任何事物BHO和IE浏览器扩展。我读到的体系结构和相关信息从MSDN文章。
但我从CodeProject上从我最好的BHO的了解。我这里列出一些问题,我面对和解决这些问题的。Microsoft.mshtml.dll和Shdocvw.dll
我是BHO的工具栏上的工作,我是试图访问对象元素(LT; objectgt;标签),图像元素(LT; imggt;标签),并嵌入元素(LT; embedgt;标签)。我不知道如何让这些元素。
我有两个解决方案:使用JavaScript来获取一个元素。直接从网页检索对象[想从IE浏览器开发工具栏]
我用他们两个,因为在许多情况下,第二种方法无法检测到对象标记。注射的JavaScript在网页
我们可以在任何网页在IE中注入我们自己的JavaScript。

//Explorer is Object of SHDocVw.WebBrowserClass

HTMLDocument htmlDoc = (HTMLDocument)this.Explorer.IWebBrowser_Document;



//inject Script

htmlDoc啷parentWindow.execScript("alert('hello world !!')", "javascript");
处理Web文档事件
您可以直接从你的BHO事件处理的文件,如下:{C}
是这种方法的问题。停止执行上述代码的浏览器中的实际事件。 Web浏览器上的事件不会被触发。换句话说,Web浏览器的事件被锁定。这是一个恼人的问题,但我发现这个问题的解决方案。
namespace MyToolBar

{

    public delegate void DOMEvent(mshtml.IHTMLEventObj e);

    public classDOMEventHandler

    {

        public DOMEvent Handler;

        DispHTMLDocument Document;

        public DOMEventHandler(DispHTMLDocument doc)

        {

            this.Document = doc;

        }

        [DispId(0)]

        public voidCall()

        {

            Handler(Document.parentWindow.@event);

        }

    }

}

上面的类可以用作:
//Explorer is Object of SHDocVw.WebBrowserClass

HTMLDocument htmlDoc =(HTMLDocument)this.Explorer.IWebBrowser_Document;



DispHTMLDocument doc = (DispHTMLDocument ) htmlDoc



DOMEventHandler onmousedownhandler = newDOMEventHandler (doc); 

onmousedownhandler.Handler += new DOMEvent(Mouse_Down); 

doc.onmousedown = onmousedownhandler;



//mouse Down Can be like this

public void Mouse_Down(mshtml.IHTMLEventObje)

{

    MessageBox.Show(e.srcElement.tagName);

}
从网页收集的所有图片
我试图从一个网页访问的所有图像。这是可以做到下列方式之一。使用Document.Images集合
//Explorer is Object of SHDocVw.WebBrowserClass

HTMLDocument htmlDoc = (HTMLDocument)this.Explorer.IWebBrowser_Document;

//get all the images of document

IHTMLElementCollection imgs = htmlDoc.images;

foreach (HTMLImgClass imgTag in imgs)

{

    MessageBox.Show(imgTag.src);

}
使用的getElementsByTagName
HTMLDocument htmlDoc = (HTMLDocument)this.Explorer.IWebBrowser_Document;

//get all the images of document



IHTMLElementCollection imgs = htmlDoc.getElementsByTagName("img");

foreach (HTMLImgClass imgTag in imgs)

{

    MessageBox.Show(imgTag.src);

}
框架和iframe的访问内容
最大的问题是访问框架和iframe的内容。我尝试了很多内容,从框架和iframe访问。但它总是给我一个IFrameElement或拒绝访问异常。
IHTMLElementCollection frames = 

   (IHTMLElementCollection) htmlDoc啷getElementsByTagName("frame");



if (frames != null)

{

    foreach (IHTMLElement frminframes)

    {

        (HTMLFrameElement)frm).contentWindow.execScript(

                'alert('Hello From Frame')',"javascript");

    }

}

使用上面的代码,我是能够访问的框架,但它给我一个拒绝访问的异常。我试图附加帧/ IFRAME文档的事件,但也有同样的问题。最后,我得到了一个解决方案,从。我实现了一个解决方案,如下:
IHTMLElementCollection elcol = htmlDoc.getElementsByTagName("iframe");

foreach (IHTMLElement iel inelcol)

{

    HTMLFrameElement frm = (HTMLFrameElement )iel;

    DispHTMLDocument doc =(DispHTMLDocument)((SHDocVw.IWebBrowser2)frm).Document;

    DOMEventHandler onmousedownhandler = new DOMEventHandler (doc);

    onmousedownhandler啷Handler += new DOMEvent(Mouse_Down); 

    doc.onmousedown = onmousedownhandler;

}
获取标签/元素的所有属性
我需要得到一个标签的所有属性。属性是一样的高度,宽度,SRC,等我能够得到的所有属性如下:
IHTMLElement element;

IHTMLDOMNode nd = (IHTMLDOMNode)element;



IHTMLAttributeCollection attribs = (IHTMLAttributeCollection )nd.attributes;

try

{

    foreach (IHTMLDOMAttribute2 att in attribs)

    {

        if (((IHTMLDOMAttribute)att).specified)

        {

            MessageBox.Show(att.value);

        }

    }

}catch{}

回答

评论会员:linda8310 时间:2011/12/27
我是块在这个问题上许多天。并得到了搜索前的无奈。
感谢您的分享
评论会员:再现 时间:2011/12/27
{S0} {S1}
再现

评论会员:binhvtt 时间:2011/12/27


我有一个问题,如何自动点击OK按钮在提醒确认的JavaScript对话框
评论会员:会员1328610 时间:2011/12/27
英文不好和内容
评论会员:再现 时间:2011/12/27
大家好,

我的工作项目,该项目需要记录用户在Internet Explorer的行动。

我能够得到使用BHO的浏览事件,但无法登录菜单栏,工具栏的事件。
您的宝贵意见。
请帮助我!

感谢
评论会员:。再现 时间:2011/12/27
亲爱的Sumedh,

BHO的提供有关浏览器的事件... ...
菜单和工具栏是不是浏览器的一部分... ...
甚至发展需要的工具栏的BHO ..

再现

评论会员:llpnet 时间:2011/12/27
喜再现,

的意见表示感谢,

可以提供一些信息/工具栏/菜单栏事件
为不同的方式链接
评论会员:。再现 时间:2011/12/27
嗨,

你可以写鼠标钩子和鼠标事件,你可以找到活跃的元素,通过鼠标的位置,并可以有事件的细节以及..
如果控制下方是工具栏,那么你可以记录,否则
忽略它...

这是很典型的方式和挂钩可以崩溃您的浏览器
所以becareful ..

再现

评论会员:harshkapoors 时间:2011/12/27
以任何方式吗?

Saludos,

路易斯 - 阿尔弗雷多Lozada门户网站
微软DCE3
特鲁希略 - 秘鲁
评论会员:再现 时间:2011/12/27
其实号..
mshtml.HtmlImgClass给你一个HTML元素IMG
现在形式的SRC属性的IMG ü可以打开流
和可能得到的图像字节!! {S1}

再现

评论会员:harshkapoors 时间:2011/12/27
嗨,

我已阅读此页,impllemented的功能,但我不能得到正确的解决方案。我觉得我不能在合适的地点实施。

其实,我的工作与BHO的工作,得到网站的网址和访问的内容/ iframe标记,为此,我首先注册。

公共无效OnDocumentComplete(pDisp对象,参考对象的URL)
{
HTMLIFrame tempElement document.getElementsByTagName("IFRAME")的foreach()
{
System.Windows.Forms.MessageBox.Show(URL.ToString ());{ BR} }
}

公众诠释SetSite(目标网站)
 0; {

 60; (网站!= NULL)
& #160; {
web浏览器(web浏览器)的网站;
webBrowser.DocumentComplete =新DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete)
}
 0; ELSE
{
webBrowser.DocumentComplete =新DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete)
&# 160;网页浏览器= NULL;
}

返回0;  60; }

我取iframe的网址,但我怎么能访问iframe的标签?

我已经实现它呢?

请给我一个解决方案。

Thanx提前

关于
严酷的
评论会员:再现 时间:2011/12/27
喜苛刻...
不使用设置站点..这里是小片段,这将有助于您....{ BR}
[Guid("Guid-Guid-Guid-Guid-Guid")]

    [BandObject("ToolBar", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar, HelpText = "ToolBar")]

    [ComVisible(true), ClassInterface(ClassInterfaceType.None)]

    public partial class ToolBar : BandObject

    {

public void ToolBar()

 

{

         this.Load += new EventHandler(ToolBar_Load);

 

} //end of constructor



 

        void ToolBar_Load(object sender, EventArgs e)

        {

            try

            {

              this.Explorer.DownloadComplete += new DWebBrowserEvents2_DownloadCompleteEventHandler(Explorer_DownloadComplete);

//you can also use Explorer_DocumentComplete event 

             }catch(){//handle ex here}

}//end if Load function



   void Explorer_DownloadComplete()

        {

            try

            {

                IHTMLElementCollection elcol = htmlDoc.getElementsByTagName("iframe");

                foreach (IHTMLElement iel in elcol)

                {

                    HTMLFrameElement frm = (HTMLFrameElement)iel;

 

                    DispHTMLDocument doc = (DispHTMLDocument)((SHDocVw.IWebBrowser2)frm).Document;

                    MessageBox.Show(doc.body.innerHTML); //do your processing here...

                 } 

               

             }catch(){//handle ex here}

        }//end of  Explorer_DownloadComplete



}//end of class

编码快乐...
{S3}

再现

评论会员:harshkapoors 时间:2011/12/27
喜再现,

这里(下图)是我得到一个URL的完整代码,如你所知,我的下一个目标阅读IFRAME标签。和你所提到的代码只是为了获取IFRAME标签。

我已经使用这个代码,但没有得到蚂蚁的解决方案。
.................................................. .......................{ BR}
IHTMLElementCollection elcol = htmlDoc.getElementsByTagName("IFRAME");
IHTMLElement elcol物资的foreach()
  ; {
 0; HTMLFrameElement FRM =(HTMLFrameElement)物资;
 60; DispHTMLDocument DOC =(DispHTMLDocument)((SHDocVw.IWebBrowser2)FRM)文件;
 0; System.Windows.Forms.MessageBox.Show(doc.body.innerHTML)/ /这里做你的处理... ...
}
.................................................. .......................{ BR} 一件事请描述我BandObject类?哪个阶级和Htmldoc对象?
,我想的HTMLDocument,但我们将分配中的任何值,然后呢?
请你提到,在那里我有使用给定的代码?
公共无效OnDocumentComplete(pDisp对象,参考对象的URL)
{
HTMLIFrame tempElement document.getElementsByTagName("IFRAME")的foreach()
{
System.Windows.Forms.MessageBox.Show(URL.ToString ());{ BR}}
}

公众诠释SetSite(目标网站)

(网站!= NULL)
{
web浏览器(web浏览器)的网站;
webBrowser.DocumentComplete =新DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete)
}
ELSE
webBrowser.DocumentComplete =新DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete)
网页浏览器= NULL;
} 返回0;}

公众诠释GetSite(参考GUID GUID出的IntPtr ppvSite)
{
 0; IntPtr的朋克= Marshal.GetIUnknownForObject(web浏览器);
INT HR = Marshal.QueryInterface(朋克,楼盘GUID,出ppvSite)
&# 160;
Marshal.Release(朋克); 0; 返回小时;

 0; }

公共静态字符串BHOKEYNAME ="SOFTWARE \ \ MICROSOFT \ \ WINDOWS \ \ \ \资源管理器\ \浏览器助手对象";

&# 160; [ComRegisterFunction]
静态无效RegisterBHO(类型为type)
{
的RegistryKey的RegistryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME,真正)

(的RegistryKey == NULL)
的RegistryKey = Registry.LocalMachine.CreateSubKey(BHOKEYNAME);

&# 160; 字符串GUID = type.GUID.ToString("B")
registryKey.OpenSubKey的RegistryKey ourKey =(GUID);

(ourKey == NULL)
ourKey = registryKey.CreateSubKey(GUID);

ourKey.SetValue("好吧",1);
  ; registryKey.Close()
ourKey.Close()
}

  ; [ComUnregisterFunction]
& #160;静态无效UnregisterBHO(类型为type)
&# 160; {
的RegistryKey的RegistryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME,真正)
字符串GUID = type.GUID.ToString("B")

  ;(的RegistryKey!= NULL)
  ;
registryKey.DeleteSubKey(GUID,FALSE);   ; }

}

预先感谢

严酷的
评论会员:再现 时间:2011/12/27
嗨,苛刻的

请阅读
文章[]代码项目。
这是很好的文章,以了解BHO的.. 我张贴... ...它是继承类帕维尔Zolnikov代码的代码。他已经为我们做了几乎所有的东西..包括getSite和SetSite。
而其余的类,你必须参考MSDN。
最终的答案在哪里写代码?我曾提到它在给你最后的答案...
再次请参阅该代码..
我写了一个完整的类演示继承BHO(帕维尔Zolnikov)
然后构造函数,负载类和文档事件的事件以及

编码快乐...
{S1}

再现

评论会员:harshkapoors 时间:2011/12/27
我亲爱的,

仍然没有工作,我的DLL没有被注册。 {五}

我提供的解决方案。

严酷的
评论会员:harshkapoors 时间:2011/12/27
u能给予确切的错误/问题的情况呢??

再现

评论会员:再现 时间:2011/12/27
您好,

我已经通过BandObject类了,我发现很多事情是不是对我有用的,所以我检索onle GetSite,SetSite功能,我已经执行,其余部分ü给我。我使用了两个来回从GAC中注册和未注册的DLL功能。
现在DLL没有被注册。

"RegAsm:警告RA0000:注册一个​​无符号的装配/ CODEBASE可以使用接口与其他应用程序,可在同一台计算机上安装您的程序集。"

发生这样的事情 - 这个问,当我们不使用公共访问修饰符。但我使用的公共类工具栏,但sprob仍然相同。

等待UR答复

严酷的
评论会员:tsahiB 时间:2011/12/27
您好,
这里是我的完整代码,仍然是没有找到iframe的标签。
-------------------------------------------------- -----------------------{ BR}
使用系统;
使用System.Collections.Generic;
使用System.Text;
使用System.Runtime.InteropServices;
使用System.Web.UI.HtmlControls;
使用System.Web.UI.WebControls程序;
使用MSHTML;
使用的System.Web;
使用SHDocVw;
使用System.Diagnostics;
的Microsoft.Win32;

命名空间BHO_HelloWorld
{

公共类的工具栏:IObjectWithSite
{
&# 160; SHDocVw.WebBrowser的WebBrowser;
SHDocVw.WebBrowserClass资源管理器=新WebBrowserClass()
 0; 公共无效"工具栏()
{

  ; }

公共无效Explorer_DownloadComplete(pDisp对象,参考对象的URL)
&# 160; {
尝试
{
  ; System.Windows.Forms.MessageBox.Show(URL.ToString ());{ BR} 的HTMLDocument Htmldoc中=(的HTMLDocument)this.Explorer.IWebBrowser_Document;
IHTMLElementCollection elcol = htmlDoc.getElementsByTagName("IFRAME");
IHTMLElement elcol物资的foreach()
& #160; {
HTMLFrameElement FRM =(HTMLFrameElement)物资;
  ;DispHTMLDocument DOC =(DispHTMLDocument)((SHDocVw.IWebBrowser2)FRM)文件;
System.Windows.Forms.MessageBox.Show(doc.body.innerHTML)/ /这里做你的处理... ...
&# 160; }
}
赶上
& #160; {/ /这里处理前
& #160; }
Explorer_DownloadComplete
/ /结束}
公众诠释SetSite(目标网站)
{

  ; (网站!= NULL)
 60; {
&# 160;/ / System.Windows.Forms.MessageBox.Show("苛刻卡普尔");
web浏览器(web浏览器)的网站;
  ; webBrowser.DocumentComplete =新DWebBrowserEvents2_DocumentCompleteEventHandler(this.Explorer_DownloadComplete)
 60; }
& #160; ELSE
{
 60; / / System.Windows.Forms.MessageBox.Show("HarshKapoor");
  ; webBrowser.DocumentComplete =新DWebBrowserEvents2_DocumentCompleteEventHandler(this.Explorer_DownloadComplete)
 0;网页浏览器= NULL;
}
&# 160;
返回0; }
& #160; 公众诠释GetSite(参考GUID GUID出的IntPtr ppvSite)
& #160; {
IntPtr的朋克= Marshal.GetIUnknownForObject(web浏览器);
 60; INT HR = Marshal.QueryInterface(朋克,楼盘GUID,出ppvSite)
 0;
Marshal.Release(朋克); 返回小时;

}

 0; 公共静态字符串BHOKEYNAME ="SOFTWARE \ \ MICROSOFT \ \ WINDOWS \ \ \ \资源管理器\ \浏览器助手对象";

[ComRegisterFunction]
静态无效RegisterBHO(类型为type)
{
& #160;的RegistryKey的RegistryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME,真正)

&# 160;(的RegistryKey == NULL)
&# 160; 的RegistryKey = Registry.LocalMachine.CreateSubKey(BHOKEYNAME);

字符串GUID = type.GUID.ToString("B")
& #160; registryKey.OpenSubKey的RegistryKey ourKey =(GUID);

(ourKey == NULL)
ourKey = registryKey.CreateSubKey(GUID);

  ; ourKey.SetValue("好吧",1);
registryKey.Close()
&# 160; ourKey.Close()
&# 160; }

[ComUnregisterFunction]
静态无效UnregisterBHO(类型为type)
{
&# 160; 的RegistryKey的RegistryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME,真正)
&# 160;字符串GUID = type.GUID.ToString("B")

(的RegistryKey!= NULL)

registryKey.DeleteSubKey(GUID,FALSE); }
  ; 类
/ /结束}
}
评论会员:再现 时间:2011/12/27
您好恶劣...
很抱歉晚回覆..

我想建议你... ...继承您的工具栏... 帕维尔Zolnikov类。[

他做的事情最确切方式。
请尝试使用它,研究它完全,如果你想编写自己的。

编码快乐!!
{S1}

修改日(星期二),2009年1月27日,11:20 PM
评论会员:tsahiB 时间:2011/12/27
我是一个小白到C#的问题,对不起

我使用的帕维尔Zolnikov例如。
我创建了一个新的类,从HelloWorldBar
继承有我有一个函数叫做ExplorerOnDocumentComplete。有我要处理的所有事件。在它里面,我已经进入你的代码

这是帕维尔SetSite(最后一行是我的)

.

.

try

{

object w;

sp.QueryService( 

ref guid,

ref riid,

out w );

Explorer = (WebBrowserClass)Marshal.CreateWrapperOfType(

						w as IWebBrowser,

						typeof(WebBrowserClass)

						);                 

OnExplorerAttached(EventArgs.Empty);

// I added this

Explorer.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(ExplorerOnDocumentComplete);           


它的工作方式?
我的理解,如果我想rehook我的所有事件的时间,那么所有的代码(所有的事件,我想赶上)应在我的功能,右
评论会员:?再现 时间:2011/12/27
你应该像如下的代码。 ..

    

    [Guid("AE07141B-45D4-4a98-5F68-0333EA26E115")] //your GUID goes here

    [BandObject("YourNewChildClass", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar, HelpText = "YourNewChildClass")]

    [ComVisible(true), ClassInterface(ClassInterfaceType.None)]

    public partial class YourNewChildClass: BandObject//Class from Pavel Zolnikov example

    {

 

         .

         .

         . //declaration and other functions e.g constructor etc

         .

 

 void YourNewChildClass_Load(object sender, EventArgs e) //load function of your class ..this is similar to Form Load event

   {

   try

   {

   this.Explorer.DownloadComplete += new DWebBrowserEvents2_DownloadCompleteEventHandler(Explorer_DownloadComplete);

                   

   }

   catch (Exception ex)

   {

   //Something was wrong

                MessageBox.Show(ex.Message);

   }

   } //end of Load function..



 

}//end of YourNewChildClass

快乐编码
{S1}!

再现

评论会员:tsahiB 时间:2011/12/27
首先,感谢再现您的帮助
我有3个问题:
1。在Mouse_Down事件浏览器停止后的MessageBox。这意味着,当我点击链接(在资源管理器)我得到的MessageBox
但浏览器不重定向我的页面。我应该怎么办?
2。我怎么知道哪个元素触发事件? (按钮,复选框,文本框,纯文本)?
当我调试(点击F5,我碰到一个错误"的错误,而试图运行项目:无法启动调试"。你
知道我为什么得到这个? (debuuging是当我使用"附加到进程")

感谢
评论会员:再现 时间:2011/12/27
您好亲爱的
针对此问题,请阅读文章的"处理Web文档事件"
更详细...


保持编码....

再现