Download file and automatically save it to folder

后端 未结 6 577
夕颜
夕颜 2020-12-01 07:21

I\'m trying to make a UI for downloading files from my site. The site have zip-files and these need to be downloaded to the directory entered by the user. However, I can\'t

相关标签:
6条回答
  • 2020-12-01 07:28

    Why not just bypass the WebClient's file handling pieces altogether. Perhaps something similar to this:

        private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            e.Cancel = true;
            WebClient client = new WebClient();
    
            client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(client_DownloadDataCompleted);
    
            client.DownloadDataAsync(e.Url);
        }
    
        void client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            string filepath = textBox1.Text;
            File.WriteAllBytes(filepath, e.Result);
            MessageBox.Show("File downloaded");
        }
    
    0 讨论(0)
  • 2020-12-01 07:28

    A much simpler solution would be to download the file using Chrome. In this manner you don't have to manually click on the save button.

    using System;
    using System.Diagnostics;
    using System.ComponentModel;
    
    namespace MyProcessSample
    {
        class MyProcess
        {
            public static void Main()
            {
                Process myProcess = new Process();
                myProcess.Start("chrome.exe","http://www.com/newfile.zip");
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-01 07:30

    If you don't want to use "WebClient" or/and need to use the System.Windows.Forms.WebBrowser e.g. because you want simulate a login first, you can use this extended WebBrowser which hooks the "URLDownloadToFile" Method from the Windows URLMON Lib and uses the Context of the WebBrowser

    Infos: http://www.pinvoke.net/default.aspx/urlmon/URLDownloadToFile%20.html

    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace dataCoreLib.Net.Webpage
    {
            public class WebBrowserWithDownloadAbility : WebBrowser
            {
                /// <summary>
                /// The URLMON library contains this function, URLDownloadToFile, which is a way
                /// to download files without user prompts.  The ExecWB( _SAVEAS ) function always
                /// prompts the user, even if _DONTPROMPTUSER parameter is specified, for "internet
                /// security reasons".  This function gets around those reasons.
                /// </summary>
                /// <param name="callerPointer">Pointer to caller object (AX).</param>
                /// <param name="url">String of the URL.</param>
                /// <param name="filePathWithName">String of the destination filename/path.</param>
                /// <param name="reserved">[reserved].</param>
                /// <param name="callBack">A callback function to monitor progress or abort.</param>
                /// <returns>0 for okay.</returns>
                /// source: http://www.pinvoke.net/default.aspx/urlmon/URLDownloadToFile%20.html
                [DllImport("urlmon.dll", CharSet = CharSet.Auto, SetLastError = true)]
                static extern Int32 URLDownloadToFile(
                    [MarshalAs(UnmanagedType.IUnknown)] object callerPointer,
                    [MarshalAs(UnmanagedType.LPWStr)] string url,
                    [MarshalAs(UnmanagedType.LPWStr)] string filePathWithName,
                    Int32 reserved,
                    IntPtr callBack);
    
    
                /// <summary>
                /// Download a file from the webpage and save it to the destination without promting the user
                /// </summary>
                /// <param name="url">the url with the file</param>
                /// <param name="destinationFullPathWithName">the absolut full path with the filename as destination</param>
                /// <returns></returns>
                public FileInfo DownloadFile(string url, string destinationFullPathWithName)
                {
                    URLDownloadToFile(null, url, destinationFullPathWithName, 0, IntPtr.Zero);
                    return new FileInfo(destinationFullPathWithName);
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-01 07:30

    Well, your solution almost works. There are a few things to take into account to keep it simple:

    • Cancel the default navigation only for specific URLs you know a download will occur, or the user won't be able to navigate anywhere. This means you musn't change your website download URLs.

    • DownloadFileAsync doesn't know the name reported by the server in the Content-Disposition header so you have to specify one, or compute one from the original URL if that's possible. You cannot just specify the folder and expect the file name to be retrieved automatically.

    • You have to handle download server errors from the DownloadCompleted callback because the web browser control won't do it for you anymore.

    Sample piece of code, that will download into the directory specified in textBox1, but with a random file name, and without any additional error handling:

    private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) {
        /* change this to match your URL. For example, if the URL always is something like "getfile.php?file=xxx", try e.Url.ToString().Contains("getfile.php?") */
        if (e.Url.ToString().EndsWith(".zip")) {
            e.Cancel = true;
            string filePath = Path.Combine(textBox1.Text, Path.GetRandomFileName());
            var client = new WebClient();
            client.DownloadFileCompleted += client_DownloadFileCompleted;
            client.DownloadFileAsync(e.Url, filePath);
        }
    }
    
    private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) {
        MessageBox.Show("File downloaded");
    }
    

    This solution should work but can be broken very easily. Try to consider some web service listing the available files for download and make a custom UI for it. It'll be simpler and you will control the whole process.

    0 讨论(0)
  • 2020-12-01 07:44

    Take a look at http://www.csharp-examples.net/download-files/ and msdn docs on webclient http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx

    My suggestion is try the synchronous download as its more straightforward. you might get ideas on whether webclient parameters are wrong or the file is in incorrect format while trying this.

    Here is a code sample..

    private void btnDownload_Click(object sender, EventArgs e)
    {
      string filepath = textBox1.Text;
      WebClient webClient = new WebClient();
      webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
      webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
      webClient.DownloadFileAsync(new Uri("http://mysite.com/myfile.txt"), filepath);
    }
    
    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
      progressBar.Value = e.ProgressPercentage;
    }
    
    private void Completed(object sender, AsyncCompletedEventArgs e)
    {
      MessageBox.Show("Download completed!");
    }
    
    0 讨论(0)
  • 2020-12-01 07:50

    My program does exactly what you are after, no prompts or anything, please see the following code.

    This code will create all of the necessary directories if they don't already exist:

    Directory.CreateDirectory(C:\dir\dira\dirb);  // This code will create all of these directories  
    

    This code will download the given file to the given directory (after it has been created by the previous snippet:

    private void install()
        {
            WebClient webClient = new WebClient();                                                          // Creates a webclient
            webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);                   // Uses the Event Handler to check whether the download is complete
            webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);  // Uses the Event Handler to check for progress made
            webClient.DownloadFileAsync(new Uri("http://www.com/newfile.zip"), @"C\newfile.zip");           // Defines the URL and destination directory for the downloaded file
        }
    

    So using these two pieces of code you can create all of the directories and then tell the downloader (that doesn't prompt you to download the file to that location.

    0 讨论(0)
提交回复
热议问题