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