您可以注入 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 控件下载文件时绕过保存对话框的最佳解决方案。我希望这对其他人也有帮助。