仅为我的应用程序实施IDownloadManger

我在WinForms应用程序中使用WebBrowser控件,并按照此处的说明实现了我自己的下载管理器。

我的自定义下载管理器可以工作,但也会覆盖Internet Explorer的下载管理Internet Explorer *。 有没有办法只在我的应用程序运行时出现自定义下载管理器? 或者,当我的申请结束时,有没有办法取消注册?

*我很欣赏这正是实现IDownloadManager ,而WebBrowser控件本质上就是Internet Explorer (这就是我沿着这条路走下去的原因)。 自定义下载管理器通过允许我知道已下载的内容以及下载位置,提供了我所需要的内容。

经过数周的研究,我终于成功地把它拼凑起来了。 在这里发布这个希望它将拯救一个人我经历过的创伤。

IServiceProvider.cs

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; namespace BrowserExample { [ComImport, ComVisible(true)] [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IServiceProvider { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int QueryService( [In] ref Guid guidService, [In] ref Guid riid, [Out] out IntPtr ppvObject); } } 

IDownloadManager.cs

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; namespace BrowserExample { [ComVisible(false), ComImport] [Guid("988934A4-064B-11D3-BB80-00104B35E7F9")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDownloadManager { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int Download( [In, MarshalAs(UnmanagedType.Interface)] IMoniker pmk, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In, MarshalAs(UnmanagedType.U4)] UInt32 dwBindVerb, [In] int grfBINDF, [In] IntPtr pBindInfo, [In, MarshalAs(UnmanagedType.LPWStr)] string pszHeaders, [In, MarshalAs(UnmanagedType.LPWStr)] string pszRedir, [In, MarshalAs(UnmanagedType.U4)] uint uiCP); } } 

DownloadManagerImplementation.cs

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices.ComTypes; using System.Windows.Forms; namespace BrowserExample { [System.Runtime.InteropServices.ComVisible(true)] [System.Runtime.InteropServices.Guid("bdb9c34c-d0ca-448e-b497-8de62e709744")] public class DownloadManagerImplementation : IDownloadManager { ///  /// Return S_OK (0) so that IE will stop to download the file itself. /// Else the default download user interface is used. ///  public int Download(IMoniker pmk, IBindCtx pbc, uint dwBindVerb, int grfBINDF, IntPtr pBindInfo, string pszHeaders, string pszRedir, uint uiCP) { // Get the display name of the pointer to an IMoniker interface that specifies // the object to be downloaded. string name = string.Empty; pmk.GetDisplayName(pbc, null, out name); if (!string.IsNullOrEmpty(name)) { Uri url = null; bool result = Uri.TryCreate(name, UriKind.Absolute, out url); if (result) { //Implement your custom download manager here //Example: //WebDownloadForm manager = new WebDownloadForm(); //manager.FileToDownload = url.AbsoluteUri; //manager.Show(); MessageBox.Show("Download URL is: " + url); return 0; //Return S_OK } } return 1; //unspecified error occured. } } 

ExtendedBrowser.cs

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace BrowserExample { public class ExtendedBrowser : WebBrowser { protected sealed class WebBrowserControlSite : WebBrowser.WebBrowserSite, IServiceProvider { DownloadManagerImplementation manager; public WebBrowserControlSite(WebBrowser host) : base(host) { manager = new DownloadManagerImplementation(); } public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject) { Guid SID_SDownloadManager = new Guid("988934A4-064B-11D3-BB80-00104B35E7F9"); Guid IID_IDownloadManager = new Guid("988934A4-064B-11D3-BB80-00104B35E7F9"); if ((guidService == IID_IDownloadManager && riid == IID_IDownloadManager)) { ppvObject = Marshal.GetComInterfaceForObject(manager, typeof(IDownloadManager)); return 0; //S_OK } ppvObject = IntPtr.Zero; return unchecked((int)0x80004002); //NON_INTERFACE (use the default, please) } } protected override WebBrowserSiteBase CreateWebBrowserSiteBase() { return new WebBrowserControlSite(this); } } } 

要使用它,只需实例化ExtendedBrowser即可。

Form1.cs的

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace BrowserExample { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { var browser = new ExtendedBrowser(); this.Controls.Add(browser); browser.Dock = DockStyle.Fill; browser.Navigate("http://stackoverflow.com"); } } }