抑制 WebBrowser 控件中的保存/打开对话框

Posted

技术标签:

【中文标题】抑制 WebBrowser 控件中的保存/打开对话框【英文标题】:Suppressing the Save/Open Dialog box in a WebBrowser control 【发布时间】:2011-04-02 02:51:05 【问题描述】:

我有一个 WebBrowser 控件,它会自动将我登录到网站并尝试自动下载 CSV 数据。一切正常,除了当它尝试下载 CSV 数据时,它会弹出一个对话框,询问我是要保存文件还是打开它(就像在 IE 中一样)。我要做的是自动将 CSV 文件下载到我选择的文件中(或者更好的是,将 CSV 文件直接保存到字符串变量中)。我似乎无法弄清楚如何抑制对话框并自动捕获下载。我已经搜索并找到了一些解决方案,但是它们对我不起作用,因为:

1) 我现在使用的是 GUI。所有这些都在一个类中完成(因此,SendKeys 等方法不是可行的解决方案)

2) 下载来自安全站点并需要身份验证。 WebBrowser 控件为我处理所有这些,但如果我使用 WebRequest 和 WebResponse 来尝试捕获下载,我将不再通过身份验证。

我正在使用 C#。任何帮助将不胜感激。

【问题讨论】:

你想明白了吗?我正在尝试做同样的事情。 @Erx_VB.NExT.Coder -- 我所做的只是使用 WebRequest 和 WebResponse 来获取我的下载。 请看这个链接***.com/a/16193614/2315806它解决了我的问题。 【参考方案1】:

您可以连接自己的 IDownloadManager 实现,该实现会安静地下载。对于 Windows 窗体,这意味着您需要重写 WebBrowser.CreateWebBrowserSiteBase 方法以提供您的扩展控制站点。详情请查看Webbrowser Control Downloads。

【讨论】:

【参考方案2】:

您可以注入 javascript 以将文件从 WebBrowser 控件返回到您的 C# 代码,并将其保存在您想要的任何位置,而不会弹出另存为对话框。如果自动化的网站需要登录并实现会话或请求验证等,注入 JavaScript 真的很有帮助。

其逻辑是注入以字节形式下载文件的 JavaScript(在 WebBrowser 控件中),然后将字节转换为 base64 字符串并将 base64 字符串返回给 C#。然后 C# 代码会将 base64 字符串转换为字节,并将字节作为文件保存在磁盘上。它可以是任何文件,例如Excel 或 PDF 等。

因为WebBrowser控件是基于Internet Explorer的,所以不支持fetch API,所以必须使用XMLHttpRequest。当 WebBrowser 控件中的页面准备好下载链接后,将以下脚本注入到 WebBrowser 控件中的文档中:

string strScript = "var fileInBase64; " +
    "var oReq = new XMLHttpRequest();" +
    "            oReq.onload = function(e) " +
    "                var buffer = oReq.response;" +
    "                //Convert response to base64 string" +
    "                var reader = new FileReader();" +
    "                reader.readAsDataURL(buffer);" +
    "                reader.onloadend = function() " +
    "                    fileInBase64 = reader.result;//Buffer value in fileInBase64" +
    "                " +
    "            ;" +
    "            oReq.open('GET', 'downloadLink');" +
    "            oReq.responseType = 'blob';" +
    "            oReq.send(); ";
htmlElement head = wb.Document.GetElementsByTagName("head")[0];
HtmlElement script = wb.Document.CreateElement("script");
script.SetAttribute("text", strScript);
head.AppendChild(script);

因为 XMLHttpRequest 的结果可能不会立即准备好,所以要检索 fileInBase64 变量的值,在等待 1 或 2 秒后注入其他脚本或添加另一个条件(或逻辑)以等待 fileInBase64 变量中的文件未准备好。

string strScript = "function getBase64()return fileInBase64;";
HtmlElement head = wb.Document.GetElementsByTagName("head")[0];
HtmlElement script = wb.Document.CreateElement("script");
script.SetAttribute("text", strScript);
head.AppendChild(script);
object o = wb.Document.InvokeScript("getBase64");

现在对象 o 将文件作为 base64 字符串并准备好保存在您想要的任何位置。使用以下代码将其保存在磁盘上:

o = o.ToString().Replace("data:application/excel;base64,", ""); //replace to make a valid base64 string.
System.IO.File.WriteAllBytes("D:/file.xls", Convert.FromBase64String(o.ToString()));

对我来说,这是从 WebBrowser 控件下载文件时绕过保存对话框的最佳解决方案。我希望这对其他人也有帮助。

【讨论】:

【参考方案3】:

您不能取消文件下载对话框,因为这会带来重大的安全风险。如果你想让这个过程自动进行,我建议你调查其他途径来验证你的请求。

【讨论】:

确实不会有那么大的安全风险,对吧?因为我需要在下载之前先验证自己。 @alex 当然你可以删除它,有几种方法,我正在阅读一本关于子类化的书,它告诉我如何去做。如果有意愿,总会有办法:)。

以上是关于抑制 WebBrowser 控件中的保存/打开对话框的主要内容,如果未能解决你的问题,请参考以下文章

WPF WebBrowser抑制Suppress 弹出 脚本错误 对话框 但是样式改变 需要继续改善

C# 如何打开一个文件的属性窗口,还有如何打开WebBrowser控件加载的网页的属性。

WebBrowser 控件和 JavaScript 错误

利用WebBrowser控件实现百度自动搜索

Silverlight 中的webBrowser控件打开的网页怎么才能加载ActiveX控件

在新选项卡中打开链接(WebBrowser 控件)