描述:
问题的提出:为了有效捕获Webbrowser下载文件的事件,于是实现IDownloadManager接口。实现接口后不仅仅可以获得通知,还能在接口参数中获得下载的URL。这在很多时候是很有用的。
然而实现IDownloadManager接口之后,出现一个奇怪的问题:当下载某些文件,比如论坛、163邮箱的附件的时候,
IE的表现为:弹出一个对话框,用户可以选择“打开”、“保存”和“取消”。若选择保存(点 保存 按钮),出现选择保存路径的对话框。
Webbrowser的表现为:直接出现选择保存路径的对话框。 就效果来说,就好像有一只无形的手点击了“保存”按钮!
这对于某些用户来说是不方便的。比如附件是个ppt或txt等文件,某些用户喜欢直接点“打开”来查看内容。而实现IDownloadManager接口之后的Webbrowser就没有机会选择“打开”了……
在IDownloadManager的Download方法中,各种返回值都测试过了,包括E_NOTIMPL、E_FAIL、S_OK,S_OK为取消(禁止)下载,其他返回值均无什么改变,都是那种“好像有一只无形的手点击了“保存”按钮” 那种下载。
我曾经仔细测试过,就效果来说,IE的效果与在下载的时候获得URL之后,用DoFileDownloadEx的效果一样。而Webbrowser的效果与DoFileDownload一样。于是我尝试过用DoFileDownloadEx下载URL,再返回S_OK,效果是出来了,但在163信箱中,下载一次附件之后又要求重新登录,所以看来这个办法是无效的,会导致cookie失效。
我做过测试,对于那些会直接出现“另存为”的情况,其在IDownloadManager的Download方法中的pszHeaders=0,而正常出现 打开 保存 取消 对话框的情况下不等于0,其对应的值一般为“Accept-Language: zh-cn”,于是我判断:pszHeaders=0的时候将“Accept-Language: zh-cn”写回pszHeaders,也没什么改善。
比较详细讨论这个接口的资料:
http://www.codeproject.com/KB/atl/vbmhwb.aspx
但这个代码是完全自己用代码来完成下载这个过程了,我所希望的是和IE一样的效果,也就是IDownloadManager_Download用其默认动作……
我到目前为止也问过一些人,基本上得出的结论是:该接口本就如此。
期待大家参与讨论,群策群力,出谋划策。不胜感激!
解决方案1:
IDownloadManager确实只是为了下载,不是为了打开,打开是IE提供的功能,当然你的程序也能加这个功能,但需要你自己实现选择对话框。如果需要直接打开文件,可以使用URLDownloadToCacheFile保存到临时文件之后再调用ShellExecute打开该文件。
如果你想修改pszHeaders代表的头信息,应该实现一个组件,它同时实现IBindStatusCallback和IHttpNegotiate两个接口,然后用RegisterBindStatusCallback把这个回调接口设置到download方法的第二个参数IBindCtx*上用来接管下载过程。在IHttpNegotiate的方法里面可以实现在发送HTTP请求之前就修改头信息。