68

Is it possible to download a file from a website in Windows Application form and put it into a certain directory?

H.B.
  • 166,899
  • 29
  • 327
  • 400
S3THST4
  • 1,025
  • 2
  • 10
  • 8
  • Mitch's comment is the most direct and most accurate answer, lol! – Cerebrus Feb 08 '09 at 07:56
  • Unless you are new to .net, I would suggest searching the MSDN documentation would help. Look for things that you want to achieve, lok at what namespace this might fit in & see if there is a class which can do that :) – shahkalpesh Feb 08 '09 at 08:08
  • 4
    @shahkalpesh - to heck with that... just google for: +C# +"download file" – Marc Gravell Feb 08 '09 at 10:04
  • @Marc: Oh sure. I don't mean to let the OP search in MSDN. The idea is to look out for docs first, google next & then post questions - if none of it helps. I mean what is the point of asking questions for which you can find something on google already? – shahkalpesh Feb 08 '09 at 10:24
  • 32
    The idea of this site is not to tell people to google for their answers, the idea of this site is for people to ask questions despite how stupid they are so that when people google in the future the answer will be right here. – Rayne Feb 08 '09 at 18:39
  • 3
    Possible duplicate of [How to download a file from a URL in C#?](http://stackoverflow.com/questions/307688/how-to-download-a-file-from-a-url-in-c) – Sandy Chapman Feb 29 '16 at 15:53

7 Answers7

121

With the WebClient class:

using System.Net;
//...
WebClient Client = new WebClient ();
Client.DownloadFile("http://i.stackoverflow.com/Content/Img/stackoverflow-logo-250.png", @"C:\folder\stackoverflowlogo.png");
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
87

Use WebClient.DownloadFile:

using (WebClient client = new WebClient())
{
    client.DownloadFile("http://csharpindepth.com/Reviews.aspx", 
                        @"c:\Users\Jon\Test\foo.txt");
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
19

You may need to know the status during the file download or use credentials before making the request.

Here is an example that covers these options:

Uri ur = new Uri("http://remotehost.do/images/img.jpg");

using (WebClient client = new WebClient()) {
    //client.Credentials = new NetworkCredential("username", "password");
    String credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes("Username" + ":" + "MyNewPassword"));
    client.Headers[HttpRequestHeader.Authorization] = $"Basic {credentials}";

    client.DownloadProgressChanged += WebClientDownloadProgressChanged;
    client.DownloadDataCompleted += WebClientDownloadCompleted;
    client.DownloadFileAsync(ur, @"C:\path\newImage.jpg");
}

And the callback's functions implemented as follows:

void WebClientDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    Console.WriteLine("Download status: {0}%.", e.ProgressPercentage);

    // updating the UI
    Dispatcher.Invoke(() => {
        progressBar.Value = e.ProgressPercentage;
    });
}

void WebClientDownloadCompleted(object sender, DownloadDataCompletedEventArgs e)
{
    Console.WriteLine("Download finished!");
}

(Ver 2) - Lambda notation: other possible option for handling the events

client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(delegate(object sender, DownloadProgressChangedEventArgs e) {
    Console.WriteLine("Download status: {0}%.", e.ProgressPercentage);

    // updating the UI
    Dispatcher.Invoke(() => {
        progressBar.Value = e.ProgressPercentage;
    });
});

client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(delegate(object sender, DownloadDataCompletedEventArgs e){
    Console.WriteLine("Download finished!");
});

(Ver 3) - We can do better

client.DownloadProgressChanged += (object sender, DownloadProgressChangedEventArgs e) =>
{
    Console.WriteLine("Download status: {0}%.", e.ProgressPercentage);

    // updating the UI
    Dispatcher.Invoke(() => {
        progressBar.Value = e.ProgressPercentage;
    });
};

client.DownloadDataCompleted += (object sender, DownloadDataCompletedEventArgs e) => 
{
    Console.WriteLine("Download finished!");
};

(Ver 4) - Or

client.DownloadProgressChanged += (o, e) =>
{
    Console.WriteLine($"Download status: {e.ProgressPercentage}%.");

    // updating the UI
    Dispatcher.Invoke(() => {
        progressBar.Value = e.ProgressPercentage;
    });
};

client.DownloadDataCompleted += (o, e) => 
{
    Console.WriteLine("Download finished!");
};
Kreshnik
  • 2,661
  • 5
  • 31
  • 39
  • If you want to use `async Task` instead of `async void` look at [this answer](http://stackoverflow.com/a/16514441/2816057) which uses `await webClient.DownloadFileTaskAsync(...)` so no need for a `DownloadDataCompleted` event – MikeT Jul 07 '16 at 17:15
13

Sure, you just use a HttpWebRequest.

Once you have the HttpWebRequest set up, you can save the response stream to a file StreamWriter(Either BinaryWriter, or a TextWriter depending on the mimetype.) and you have a file on your hard drive.

EDIT: Forgot about WebClient. That works good unless as long as you only need to use GET to retrieve your file. If the site requires you to POST information to it, you'll have to use a HttpWebRequest, so I'm leaving my answer up.

Irshad
  • 3,071
  • 5
  • 30
  • 51
FlySwat
  • 172,459
  • 74
  • 246
  • 311
  • I dont want to read it back from a slow hd.. https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse(v=vs.110).aspx – Dan Mar 24 '17 at 20:20
2

You can use this code to Download file from a WebSite to Desktop:

using System.Net;

WebClient client = new WebClient ();
client.DownloadFileAsync(new Uri("http://www.Address.com/File.zip"), Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "File.zip");
Kenneth
  • 3,957
  • 8
  • 39
  • 62
Pouya
  • 109
  • 1
  • 8
0

Try this example:

public void TheDownload(string path)
{
  System.IO.FileInfo toDownload = new System.IO.FileInfo(HttpContext.Current.Server.MapPath(path));

  HttpContext.Current.Response.Clear();
  HttpContext.Current.Response.AddHeader("Content-Disposition",
             "attachment; filename=" + toDownload.Name);
  HttpContext.Current.Response.AddHeader("Content-Length",
             toDownload.Length.ToString());
  HttpContext.Current.Response.ContentType = "application/octet-stream";
  HttpContext.Current.Response.WriteFile(patch);
  HttpContext.Current.Response.End();
} 

The implementation is done in the follows:

TheDownload("@"c:\Temporal\Test.txt"");

Source: http://www.systemdeveloper.info/2014/03/force-downloading-file-from-c.html

angelo
  • 39
  • 2
0

Also you can use DownloadFileAsync method in WebClient class. It downloads to a local file the resource with the specified URI. Also this method does not block the calling thread.

Sample:

    webClient.DownloadFileAsync(new Uri("http://www.example.com/file/test.jpg"), "test.jpg");

For more information:

http://csharpexamples.com/download-files-synchronous-asynchronous-url-c/

Irshad
  • 3,071
  • 5
  • 30
  • 51
turgay
  • 438
  • 4
  • 7