本人在用c#开发IE的BHO插件,实现从数据库中读入URL,依次自动实现访问,但遇到个问题,当url代表的是一个“下载文件的url”时,IE会自动跳出下载对话框,请问在这种情况下我怎样实现持续自动化IE?对此我采用的两个方法均不奏效
1:通过定义SHDocVw.WebBrowser接口的FileDownload事件响应,当有文件下载时,自动实现文件保存到默认文件夹。但编程实现时发现FileDownload时间根本就没有触发/或者根本没有调用此事件的响应消息(消息框没有弹出,如下)。而DocumentComplete等事件均可正确触发和响应。
代码如下:    //定义IObjectWithSite接口
    [
    ComVisible(true),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
    Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")
    ]        public interface IObjectWithSite
        {
            [PreserveSig]
            int SetSite([MarshalAs(UnmanagedType.IUnknown)]object site);
            [PreserveSig]
            int GetSite(ref Guid guid, out IntPtr ppvSite);
        }    //接口功能实现
    [ComVisible(true),
    Guid("8a194578-81ea-4850-9911-13ba2d71efbd"),
    ClassInterface(ClassInterfaceType.None)
    ]
    public class BHO:IObjectWithSite
    {
        WebBrowser webBrowser;
        public void OnWebBrowser_FileDownload(ref bool Cancel)
        {
            System.Windows.Forms.MessageBox.Show("这是一个下载文件"); //此处无任何响应
            webBrowser.Quit();
        }
        #region BHO Internal Functions
        public static string BHOKEYNAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";
        [ComRegisterFunction]
        public static void RegisterBHO(Type type){//注册此组件//}
        [ComUnregisterFunction]
        public static void UnregisterBHO(Type type){//解除此组件//}
        public int SetSite(object site)
        {
            if (site != null)
            {
                webBrowser = (WebBrowser)site;
                webBrowser.FileDownload+=new DWebBrowserEvents2_FileDownloadEventHandler(this.OnWebBrowser_FileDownload);//挂载事件处理
            }
            else
            {
                webBrowser.FileDownload -= new DWebBrowserEvents2_FileDownloadEventHandler(this.OnWebBrowser_FileDownload);
                webBrowser = null;
            }
            return 0;
        }
        public int GetSite(ref Guid guid, out IntPtr ppvSite){//getsite实现}2:上面方法不通后,又想通过定制IE下载管理实现持续自动化,但在c#下使用IDownloadManager接口总是不成功,IDownloadManager是不是可以直接使用,还是需要从其他接口继承或者查询获得?问题代码如下:
//定义IDownloadManager接口
[ComVisible(true), ComImport]
    [Guid("988934A4-064B-11D3-BB80-00104B35E7F9")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]    public interface IDownloadManager
    {        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        void Download(
            System.Runtime.InteropServices.ComTypes.IMoniker pmk,
            System.Runtime.InteropServices.ComTypes.IBindCtx pbc,
            [In, MarshalAs(UnmanagedType.U4)] UInt32 dwBindVerb,
            [In] Int32 grfBINDF,
            ref IntPtr pBindInfo,
            [In, MarshalAs(UnmanagedType.LPWStr)] string pszHeaders,
            [In, MarshalAs(UnmanagedType.LPWStr)] string pszRedir,
            [In, MarshalAs(UnmanagedType.U4)] UInt32 uiCP);
    }    //实现IDownloadManager接口功能类
     [
    ComVisible(true),
    Guid("9be66cc0-1dd1-11b2-8617-e3a3ed26e3b0"),
    ClassInterface(ClassInterfaceType.None)
    ]    public class DownloadManager : IDownloadManager
    {
        public void Download(IMoniker pmk,
            IBindCtx pbc,
            UInt32 dwBindVerb,
            int grfBINDF,
            ref IntPtr pBindInfo,
            String pszHeaders,
            String pszRedir,
            UInt32 uiCP)
        {
            System.Windows.Forms.MessageBox.Show("Extremely great sign...");      //此处也无反应      
        }        #region BHO Internal Functions
        public static string BHOKEYNAME = "Software\\Microsoft\\Internet Explorer";
        //修改HKEY_CurrentUser\Software\Microsoft\Internet Explorer下的DownloadUI的值
         //
        [ComRegisterFunction]
        public static void RegisterBHO(Type type)
        {
            RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(BHOKEYNAME, true);
            if (registryKey == null)
                registryKey = Registry.LocalMachine.CreateSubKey(BHOKEYNAME);
            registryKey.SetValue("DownloadUI", "{9be66cc0-1dd1-11b2-8617-e3a3ed26e3b0}");
            registryKey.Close();
        }        [ComUnregisterFunction]
        public static void UnregisterBHO(Type type)
        {
            RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);
            registryKey.SetValue("DownloadUI", "{802F530B-A8F6-4631-AE49-6BACAAC6373E}");
        }
        #endregion
    }

解决方案 »

  1.   

    而且非常怪的是每次我用regasm注册后,注册表的DownloadUI值是做了相应的更改,但每当我运行IE后,此值又重新回到对应于迅雷bho的CSID,不知道为什么会出现这种问题,请各位高手指点!
      

  2.   

    那vc里面是怎么实现的?ATL好像比较适合做此类工作。
      

  3.   

    应该是的,不过我把注册表中有关迅雷的BHO插件的值都改了,好像还是不行。
      

  4.   

    估计迅雷用BHO劫持了IE的下载
    这种情况下没有办法。你可以要求用户修改迅雷的选项,不监视下载。
      

  5.   

    .net下的Filedownload事件不能响应是怎么一回事呢?
    我用c#开发的BHO,如果对应的url是一个下载url,我想停止此导航,然后继续下一个url的访问,因为在.net环境下Filedownload事件响应机制好像是无效的,那能提供一个解决办法吗?
      

  6.   

    IE6的类型库有个BUG,Filedownload事件的类型错了,得用IE7的类型库,或者自己声明事件类型
    IE6.1有个BUG,如果用户在提示确认时选择了保存,那么Filedownload事件不会被触发。
      

  7.   

    那自己声明事件类型怎么写呢?想了半天也不知道从哪里下手,jiangsheng大哥能够提供一下参考资料或关键实现部分的代码吗?十分感谢
      

  8.   

    我使用的是BHO技术,事件应该都是IE触发的,我只能写事件处理程序吧?如果要自己生命事件类型,岂不是要自己实现IE浏览器的功能吗?
      

  9.   

    如果不能够实现自定义下载管理器,那通过什么方式能够区分出当前正在进行的导航页是正常的网页还是对应的下载页呢?在beforenavigate的事件处理程序里面检测什么项能够区分出来?
      

  10.   

    使用c#基于.net开发的BHO确实不响应FileDownLoad,但使用VC+ATL开发的BHO确响应了FileDownLoad事件,因此建议使用ATL库开发BHO,毕竟ATL对com的支持度较高,不用再CreateInstance麻烦了。