5

I have a WebBrowser control that is automatically logging me into a website and attempting to download CSV data automatically. Everything is working fine, except, when it tries to download the CSV data, it is popping up a dialog box, asking if I want to save the file or open it (just like in IE). What I am trying to do is automatically download the CSV file to a file of my choosing (or better, save the CSV file directly into a string variable). I can't seem to figure out how to suppress the dialog box and capture the download automatically. I've search and found a few solutions, however, they don't work for me because:

1) I am now using a GUI. All this is done in a class (therefore, methods such as SendKeys would not be a viable solution)

2) The download comes from a secure site and requires authentication. The WebBrowser control handles all that for me, but if I use a WebRequest and WebResponse to try to capture the download, I am no longer authenticated.

I am using C#. Any help would be appreciated.

Icemanind
  • 47,519
  • 50
  • 171
  • 296

3 Answers3

6

You can hook up your own IDownloadManager implementation that does download quietly. For Windows Forms, this means you need to override the WebBrowser.CreateWebBrowserSiteBase method to provide your extended control site. Check Webbrowser Control Downloads for details.

Sheng Jiang 蒋晟
  • 15,125
  • 2
  • 28
  • 46
0

You can inject JavaScript to return file to your C# code from WebBrowser control and save it wherever you want without popping up the save as dialog box. Injecting JavaScript is really helpful if a website being automated requires login and implements sessions or request verifications etc.

The logic is to inject JavaScript that downloads file as bytes (in the WebBrowser control) and then convert bytes to base64 string and return base64 string to C#. Then C# code will convert base64 string to bytes and will save bytes as file on disk. It can be any file e.g. Excel or PDF etc.

Because WebBrowser control is based on Internet Explorer, so it does not support fetch API, so you have to use XMLHttpRequest. When the page in WebBrowser control has download link ready, then inject following script into the document in WebBrowser control:

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

Because result from XMLHttpRequest may not be ready immediately, so to retrieve value of fileInBase64 variable inject other script after a wait of 1 or 2 seconds or add another condition (or logic) to wait until file in fileInBase64 variable is not ready.

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");

Now object o has the file as base64 string and is ready to be saved wherever you want. Use following code to save it on disk:

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()));

For me this was the best solution to bypass save dialog box when file is downloaded from WebBrowser control. I hope this will help others also.

-1

you can't suppress the file download dialog as that it would be a major security risk. I would suggest you investigate other routes to get your request authenticated if you want to make this process automatic.

Alex
  • 913
  • 6
  • 9
  • It really wouldn't be that big of a security risk, right? Since I am required to authenticate myself first before downloading it. – Icemanind Aug 21 '10 at 20:58
  • @alex of course you can have it removed, there are a few ways, im reading a book on subclassing that is telling me how to do it. if there is a will, there is always a way :). – Erx_VB.NExT.Coder Dec 28 '12 at 07:16