仅为我的应用程序实现IDownloadManger

TEK*_*TEK 6 c# .net-4.0 webbrowser-control winforms

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

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

*我理解这正是实施的重点IDownloadManager,而WebBrowser控制本质上就是Internet Explorer(这就是我走这条路的原因).自定义下载管理器通过允许我知道已下载的内容以及下载位置,提供了我所需要的内容.

TEK*_*TEK 8

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

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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
    {

        /// <summary>
        /// Return S_OK (0) so that IE will stop to download the file itself. 
        /// Else the default download user interface is used.
        /// </summary>
        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.
        }

    }
Run Code Online (Sandbox Code Playgroud)

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);
        }


    }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,只需实例化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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)