2011-07-21 58 views
9

Tôi đang cố gắng tạo giao diện người dùng để tải xuống tệp từ trang web của mình. Trang web có các tệp zip và những tệp này cần được tải xuống thư mục do người dùng nhập. Tuy nhiên, tôi không thể tải xuống tệp, nó chỉ mở ra từ một thư mục tạm thời.Tải xuống tệp và tự động lưu tệp vào thư mục

Code:

private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) 
{ 
     e.Cancel = true; 
     string filepath = null; 
      filepath = textBox1.Text; 
      WebClient client = new WebClient(); 
      client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); 
      client.DownloadFileAsync(e.Url, filepath); 
} 

Full sourcecode: http://en.paidpaste.com/LqEmiQ

+1

phần bài viết có liên quan của mã của bạn ở đây, trực tiếp trong câu hỏi. Không sử dụng các liên kết bên ngoài. –

+0

@Anders Abel, Đã sửa lỗi! –

+0

Bạn có đang cố gắng ghi đè việc triển khai giao diện người dùng tệp của trình duyệt không? Sẽ dễ dàng hơn nhiều nếu bạn ghi tệp vào luồng và chỉ định trong loại nội dung là tệp ... Ngoài ra nếu tôi nhớ chính xác bạn không có quyền truy cập vào hệ thống tệp của khách hàng ur ... u không thể tải tệp xuống đường dẫn trên máy khách do đó lấy nó như là một đầu vào không phải là sử dụng bất kỳ .. – Mulki

Trả lời

13

Tại sao không chỉ bỏ qua các phần xử lý tệp của WebClient hoàn toàn. Có lẽ một cái gì đó tương tự như thế này:

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

Hãy xem http://www.csharp-examples.net/download-files/ và MSDN tài liệu trên WebClient http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx

Đề nghị của tôi là cố gắng tải về đồng bộ như đơn giản của nó hơn . bạn có thể nhận được ý tưởng về việc liệu các tham số webclient có sai hay tệp có định dạng không chính xác trong khi thử điều này.

Đây là một mẫu mã ..

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

vấn đề là tôi muốn ứng dụng của tôi tải xuống tệp, chứ không phải Internet Explorer chạy với trình duyệt web. Khi tôi nhấp vào liên kết của tệp zip, cửa sổ bật lên lưu tệp sẽ xuất hiện và muốn tôi chọn mọi thứ. Tôi muốn tệp được tải xuống tự động khi người dùng nhấp vào một tệp zip. –

+0

@Victor: damn, .... Tôi hoàn toàn hiểu nhầm câu hỏi .. sửa đổi câu trả lời – Mulki

0

Vâng, giải pháp của bạn gần như hoạt động. Có một vài điều cần đưa vào tài khoản để giữ cho nó đơn giản:

  • Hủy bỏ điều hướng mặc định chỉ cho các URL cụ thể mà bạn biết một download sẽ xảy ra, hoặc người dùng sẽ không thể để di chuyển bất cứ nơi nào. Điều này có nghĩa là bạn không thay đổi URL tải xuống trang web của mình.

  • DownloadFileAsync không biết tên được máy chủ báo cáo trong tiêu đề Content-Disposition để bạn phải chỉ định một hoặc tính toán một từ URL gốc nếu có thể. Bạn không thể chỉ định thư mục và mong muốn tên tệp sẽ được truy xuất tự động.

  • Bạn phải xử lý lỗi máy chủ tải xuống từ cuộc gọi lại DownloadCompleted vì kiểm soát trình duyệt web sẽ không làm điều đó cho bạn nữa.

mẫu đoạn mã, mà sẽ tải về vào thư mục quy định tại textBox1, nhưng với một tên tập tin ngẫu nhiên, và không có bất kỳ xử lý lỗi thêm:

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

Giải pháp này nên làm việc nhưng có thể bị hỏng rất dễ dàng. Hãy thử xem xét một số dịch vụ web liệt kê các tệp sẵn có để tải xuống và tạo giao diện người dùng tùy chỉnh cho nó. Nó sẽ đơn giản hơn và bạn sẽ kiểm soát toàn bộ quá trình.

+0

Tôi cũng đã cố gắng tạo giao diện người dùng tùy chỉnh nhưng không thành công. Vẫn đang học ở một mức độ rất cơ bản và bị mắc kẹt tất cả các thời gian. Nhưng cảm ơn thời gian và sự giúp đỡ của bạn, tôi sẽ quay lại với cập nhật trạng thái. –

+0

Có thể lấy lại tên tệp từ URL, chỉ cần thử 'string filename = Path.GetFileName (e.Url.LocalPath)' – rotman

+0

Có, nhưng có nhiều trường hợp không có ý nghĩa, đặc biệt nếu tải xuống URL có dạng "download? Id = x", bạn sẽ nhận được "tải xuống" cho mọi tên tệp. –

17

Chương trình của tôi thực hiện chính xác những gì bạn đang làm sau, không có lời nhắc hoặc bất kỳ điều gì, vui lòng xem mã sau đây.

Mã này sẽ tạo ra tất cả các thư mục cần thiết nếu họ làm chưa tồn tại:

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

Mã này sẽ tải về các tập tin trao cho các thư mục nhất định (sau khi nó đã được tạo ra bởi các đoạn theo thời gian:

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 
    } 

Vì vậy, sử dụng hai đoạn mã này bạn có thể tạo tất cả các thư mục và sau đó yêu cầu trình tải xuống (không nhắc bạn tải tệp xuống vị trí đó.

+0

Điều gì sẽ được thực hiện nếu tệp này đang được tìm nạp từ một thư mục được bảo vệ trên máy chủ? Trong trường hợp đó bạn không thể lấy tệp trực tiếp từ máy chủ nhưng nếu tệp đã được máy chủ xử lý để tải xuống và gửi lại cho trình duyệt. Trong trường hợp đó, làm cách nào để lưu tệp đó mà không hiển thị lời nhắc lưu tệp? Bất kỳ đề xuất?? –

+0

@ VipinKr.Singh đó là kịch bản chính xác mà tôi đang đối mặt. –

12

Nếu bạn không muốn sử dụng "WebClient" hoặc/và cần sử dụng System.Windows.Forms.WebBrowser ví dụ: bởi vì bạn muốn mô phỏng một đăng nhập đầu tiên, bạn có thể sử dụng WebBrowser mở rộng này mà móc "URLDownloadToFile" Phương pháp từ Windows Urlmon Lib và sử dụng bối cảnh của 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); 
      } 
     } 
    } 
+2

Bạn là người đàn ông! Ive đã dành 3 ngày để tìm kiếm chính xác loại giải pháp đó! – Maciej

+1

Câu trả lời hoàn hảo. – ujjaval

+1

Giải pháp này là hoàn hảo. Tôi đã gặp vấn đề với điều này khi cố tải xuống một tệp từ trang web Laravel phía sau xác thực và Auth :: user() trả về null khi sử dụng tải xuống WebClient. –

Các vấn đề liên quan