Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用IDownloadManager的Windows窗体WebBrowser控件_C#_Winforms_Webbrowser Control_Download Manager - Fatal编程技术网

C# 使用IDownloadManager的Windows窗体WebBrowser控件

C# 使用IDownloadManager的Windows窗体WebBrowser控件,c#,winforms,webbrowser-control,download-manager,C#,Winforms,Webbrowser Control,Download Manager,我正在使用Systems.Windows.Forms.Webbrowser控件,需要覆盖下载管理器。我按照说明对表单进行了子类化,并重写了CreateWebBrowserSiteBase() DownloadManager取自上述示例 /// <summary> /// Intercepts downloads of files, to add as PDFs or suppliments /// </summary> [ComVisible(true)] [Guid("

我正在使用
Systems.Windows.Forms.Webbrowser
控件,需要覆盖下载管理器。我按照说明对表单进行了子类化,并重写了
CreateWebBrowserSiteBase()

DownloadManager
取自上述示例

/// <summary>
/// Intercepts downloads of files, to add as PDFs or suppliments
/// </summary>
[ComVisible(true)]
[Guid("bdb9c34c-d0ca-448e-b497-8de62e709744")]
[CLSCompliant(false)]
public class DownloadManager : IDownloadManager
{
    /// <summary>
    /// event called when the browser is about to download a file
    /// </summary>
    public event EventHandler<FileDownloadEventArgs> FileDownloading;

    /// <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;
        pmk.GetDisplayName(pbc, null, out name);
        if (!string.IsNullOrEmpty(name))
        {
            Uri url;
            if (Uri.TryCreate(name, UriKind.Absolute, out url))
            {
                if ( FileDownloading != null )
                {
                     FileDownloading(this, new FileDownloadEventArgs(url));
                }
                return Constants.S_OK;
            }
        }
        return 1;
    }
}
//
///截取文件下载,添加为PDF或补充文件
/// 
[ComVisible(true)]
[Guid(“bdb9c34c-d0ca-448e-b497-8de62e709744”)]
[CLSCompliant(false)]
公共类下载管理器:IDownloadManager
{
/// 
///浏览器即将下载文件时调用的事件
/// 
公共事件处理程序文件下载;
/// 
///返回S_OK(0),以便IE停止下载文件本身。
///否则将使用默认的下载用户界面。
/// 
公共int下载(IMoniker pmk、IBindCtx pbc、uint dwBindVerb、int grfBINDF、IntPtr pBindInfo、,
字符串pszHeaders、字符串pszRedir、uint uiCP)
{
//获取指向指定要下载对象的IMoniker接口的指针的显示名称。
字符串名;
pmk.GetDisplayName(pbc,null,out name);
如果(!string.IsNullOrEmpty(名称))
{
uriurl;
if(Uri.TryCreate(name,UriKind.Absolute,out-url))
{
if(文件下载!=null)
{
文件下载(这是新的FileDownloadEventArgs(url));
}
返回常数S_OK;
}
}
返回1;
}
}
问题在于
pmk.GetDisplayName
返回初始URL,而不是要下载的项目的URL。如果URI指向一个动态页面,例如,我没有得到要下载的实际文件。我需要从标题中获取URL,这样我才能获得我应该下载的实际文件

Google指出我必须创建一个
iIndStatusCallback
实现,该实现还实现了
IHttpNegotiate
IServiceProvider
来响应
IID\u IHttpNegotiate
,这样我就可以看到
IHttpNegotiate.OnResponse
。然而,我成功地实现了这一点,
QueryService
似乎只要求
IID\u IInternetProtocol
,而从不要求IID\u IHttpNegotiate


任何建议都很好。

您错过了一个呼叫:CreateBindCtx

将以下内容添加到您的DownloadManager:

   [DllImport("ole32.dll")]
        static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
然后确保在注册回调之前调用此函数。我在您的Download()方法中实现了这一点,如下所示:

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;
            pmk.GetDisplayName(pbc, null, out name);
            if (!string.IsNullOrEmpty(name))
            {
                Uri url;
                if (Uri.TryCreate(name, UriKind.Absolute, out url))
                {
                    Debug.WriteLine("DownloadManager: initial URL is: " + url);
                    CreateBindCtx(0, out pbc);
                    RegisterCallback(pbc, url);
                    BindMonikerToStream(pmk, pbc);

                    return MyBrowser.Constants.S_OK;
                }
            }
            return 1;
        }

有了它,您的IHttpNegotiate实现将被调用,您将有权访问响应头。

您好,您提到了实现IBindingStatusCallback-据我所知,接口名为IBindStatusCallback-这是一个输入错误吗?您尚未显示IBindStatusCallback的实现。MSDN提到Urlmon.dll将使用IBindStatusCallback的QueryInterface实现获取指向IHttpNegotiate接口的指针。查看是否可以将一个可编译的示例放在某个地方,以便我们对其进行测试?@SimonMourier我将在未来一两天内研究创建该示例。@Anthill是的,应该是
IBindStatusCallback
。我已经编辑了这个问题。我已经实现了msdn.microsoft.com/en us/library/ms775054(v=vs.85).aspx建议的功能。问题是,
IID\u IHttpNegotiate
从未调用
IBindStatusCallback
QueryService
(这样我就可以返回
IHttpNegotiate
实现)。它总是用
IID\u IInternetProtocol
调用。我不知道当
QueryService
请求
IID\u IInternetProtocol
@SimonMourier时返回什么。我为解决方案中带有README.txt的演示示例应用程序添加了dropbox链接。很高兴能提供帮助!它能做到你所希望的一切吗?它满足赏金的所有条件吗?是的。我以为赏金是自动颁发的。对不起。我现在意识到,我还必须以类似的方式获取HTTP响应内容,但我认为这是一个单独的问题:)我下载了一个文档,但它对我不起作用。这些活动并不成功。我从中运行了这个示例。我的盒子上有IE 10,我的盒子是64位的。嗨,山姆,下载链接断了,我会删除它以防止将来的NAA,也许你想添加一个新的。哦,梦想这个例子仍然在那里工作。
   [DllImport("ole32.dll")]
        static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
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;
            pmk.GetDisplayName(pbc, null, out name);
            if (!string.IsNullOrEmpty(name))
            {
                Uri url;
                if (Uri.TryCreate(name, UriKind.Absolute, out url))
                {
                    Debug.WriteLine("DownloadManager: initial URL is: " + url);
                    CreateBindCtx(0, out pbc);
                    RegisterCallback(pbc, url);
                    BindMonikerToStream(pmk, pbc);

                    return MyBrowser.Constants.S_OK;
                }
            }
            return 1;
        }