【问题标题】:Download file and automatically save it to folder下载文件并自动保存到文件夹
【发布时间】:2023-03-27 23:45:01
【问题描述】:

我正在尝试制作用于从我的站点下载文件的 UI。该站点有 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

【问题讨论】:

  • 直接在问题中发布代码的相关部分。不要使用外部链接。
  • 您是否试图覆盖浏览器对保存文件 UI 的实现?如果您将文件写入流并在内容类型中指定它是一个文件会容易得多......另外,如果我没记错你无权访问你的客户端的文件系统......你无法将文件下载到客户端上的路径因此将其作为输入没有任何用处..
  • 我 - 认为 - 这是一个客户端软件,即它在客户端机器上运行。
  • textBox1.Text的值是多少?
  • @Mulki,我不知道该怎么做...

标签: c# file download save


【解决方案1】:

我的程序完全按照你的要求做,没有提示什么的,请看下面的代码。

此代码将创建所有必要的目录(如果它们尚不存在):

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

这段代码会将给定的文件下载到给定的目录(在之前的sn-p创建之后:

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
    }

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

【讨论】:

  • 如果该文件是从服务器上的受保护文件夹中获取的,应该怎么做?在这种情况下,您不能直接从服务器获取文件,但如果文件已由服务器处理以下载并发送回浏览器。在那种情况下,如何在不显示保存文件提示的情况下保存该文件?有什么建议吗??
  • @VipinKr.Singh 这与我面临的情况完全相同。
【解决方案2】:

如果您不想使用“WebClient”或/并且需要使用 System.Windows.Forms.WebBrowser,例如因为你想先模拟登录,你可以使用这个扩展的 WebBrowser,它从 Windows URLMON Lib 中挂钩“URLDownloadToFile”方法并使用 WebBrowser 的上下文

信息: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);
            }
        }
    }

【讨论】:

  • 你就是男人!我花了 3 天时间寻找这种解决方案!
  • 完美答案。
  • 这个解决方案是完美的。我在尝试从 Laravel 站点下载文件时遇到了这个问题,而 Auth::user() 在使用 WebClient 下载时返回了 null。
  • @dataCore 非常感谢!非常有帮助。没有提示。我喜欢使用 p/Invoke。 :)
  • 这正是我所需要的。
【解决方案3】:

为什么不完全绕过 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");
    }

【讨论】:

    【解决方案4】:

    嗯,您的解决方案几乎可以正常工作。为了简单起见,需要考虑以下几点:

    • 仅针对您知道会发生下载的特定 URL 取消默认导航,否则用户将无法导航到任何地方。这意味着您不得更改您的网站下载 URL。

    • 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。它会更简单,您将控制整个过程。

    【讨论】:

    • 我也尝试制作自定义 UI,但没有成功。仍然在非常基础的水平上学习并且一直被卡住。但是感谢您的时间和帮助,我会返回状态更新。
    • 可以从 URL 中检索文件名,试试这个string filename = Path.GetFileName(e.Url.LocalPath)
    • 是的,但是在很多情况下它是没有意义的,特别是如果下载 URL 的形式是“download?id=x”,你会得到每个文件的“下载”名字。
    【解决方案5】:

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

    我的建议是尝试同步下载,因为它更直接。 在尝试此操作时,您可能会了解 webclient 参数是否错误或文件格式不正确。

    这是一个代码示例..

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

    【讨论】:

    • 问题是我希望我的应用程序下载文件,而不是使用 webbrowser 运行的 Internet Explorer。当我单击 zip 文件的链接时,会出现保存文件弹出窗口并希望我选择内容。我希望在用户单击 zip 时自动下载文件。
    【解决方案6】:

    更简单的解决方案是使用 Chrome 下载文件。通过这种方式,您不必手动单击保存按钮。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-07
      • 2018-03-25
      • 2014-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多