2011-07-21 109 views
9

我正在尝试制作用于从我的网站下载文件的用户界面。该网站有zip文件,这些文件需要下载到用户输入的目录中。但是,我无法成功下载该文件,只是从临时文件夹中打开。下载文件并将其自动保存到文件夹

代码:

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

全部源代码: http://en.paidpaste.com/LqEmiQ

+1

的邮政相关部分你的代码在这里,直接在问题中。不要使用外部链接。 –

+0

@Anders Abel,修正! –

+0

你是否试图覆盖保存文件UI的浏览器实现? 如果你将文件写入流并在内容类型中指定它是一个文件,将会容易得多... 另外,如果我没记错的话,你没有访问到你的客户端的文件系统...你无法下载文件到路径在客户端因此把它作为输入是没有任何用处的。 – Mulki

回答

13

为什么不完全绕过WebClient的文件处理部分。也许类似这样的东西:

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

http://www.csharp-examples.net/download-files/ 和MSDN文档上的WebClient看看 http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx

我的建议是尝试同步下载作为其更直接。 您可能会在尝试此操作时得到有关Web客户端参数是否有误或文件格式不正确的提示。

下面是一个代码示例..

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

问题是我想让我的应用程序下载该文件,而不是使用webbrowser运行的Internet Explorer。当我点击一个zip文件的链接时,保存文件弹出窗口出现,并希望我选择一些东西。我想要在用户点击一个zip文件时自动下载文件。 –

+0

@Victor:该死,....我完全误解了这个问题。 修改答案 – Mulki

0

那么,你的解决方案几乎工作。有几件事情要考虑,以保持它的简单:

  • 取消默认导航只为你知道会发生下载特定的网址,或者用户将不能够在任何地方浏览。这意味着你不能改变你的网站下载网址。

  • DownloadFileAsync不知道服务器在Content-Disposition标题中报告的名称,因此您必须指定一个,或者如果可能的话从原始URL计算一个。您不能只指定文件夹,并期望自动检索文件名。

  • 您必须处理来自DownloadCompleted回调的下载服务器错误,因为Web浏览器控件不再适合您。

样品一段代码,将下载到的textBox1指定的目录中,但有一个随机文件名,并且没有任何附加的错误处理:

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

这个解决方案应该工作,但可以很容易破碎。尝试考虑一些列出可供下载的文件的Web服务,并为其创建自定义UI。它会更简单,你将控制整个过程。

+0

我也尝试制作一个自定义用户界面,但没有成功。仍然在非常基础的水平上学习,并一直陷入困境。但感谢您的时间和帮助,我将返回状态更新。 –

+0

可以从URL中检索文件名,只要试试这个'string filename = Path.GetFileName(e.Url.LocalPath)' – rotman

+0

是的,但是在很多情况下它没有任何意义,特别是如果下载URL的格式为“download?id = x”,您将获得每个文件名的“下载”。 –

17

我的程序完全符合你的要求,没有任何提示或任何内容,请参阅下面的代码。

此代码将创建所有必需的目录,如果他们不这样做已经存在:

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

此代码将指定的文件下载到指定目录(已经由先前的片断创建后:

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 
    } 

所以使用这两段代码,你可以创建所有的目录,然后告诉下载(不提示您将文件下载到该位置。

+0

如果从服务器上的受保护文件夹中提取此文件,应该执行什么操作?在这种情况下,您无法直接从服务器获取文件,但是如果文件已被服务器处理以下载并发送回浏览器。在那种情况下,如何在不显示保存文件提示的情况下保存该文件?有什么建议么?? –

+0

@ VipinKr.Singh这是我面对的完全相同的场景。 –

12

如果不希望使用“Web客户端”或/和需要使用System.Windows.Forms.WebBrowser例如因为你想先模拟登录,就可以使用这个扩展的web浏览器鱼钩从Windows URLMON库的“URLDownloadToFile”方法,并使用web浏览器

相关信息的语境: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

你是男人!我花了3天的时间来寻找这种解决方案! – Maciej

+1

完美答案。 – ujjaval

+1

该解决方案非常完美。在尝试从认证后的Laravel站点下载文件时,我遇到了问题,而使用WebClient下载时,Auth :: user()返回null。 –

相关问题