Скачайте файл и автоматически сохраните его в папку - PullRequest
10 голосов
/ 21 июля 2011

Я пытаюсь создать интерфейс для загрузки файлов с моего сайта. На сайте есть 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

Ответы [ 6 ]

20 голосов
/ 28 июля 2011

Моя программа делает именно то, что вам нужно, никаких подсказок или чего-либо еще, пожалуйста, смотрите следующий код.

Этот код создаст все необходимые каталоги, если они еще не существуют:

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
    }

Таким образом, используя эти два фрагмента кода, вы можете создать все каталогии затем сообщите загрузчику (который не запрашивает загрузку файла в это место.

18 голосов
/ 09 июля 2015

Если вы не хотите использовать «WebClient» или / и вам нужно использовать System.Windows.Forms.WebBrowser, например, поскольку вы хотите сначала смоделировать вход в систему, вы можете использовать этот расширенный веб-браузер, который перехватывает метод «URLDownloadToFile» из Windows URLMON Lib и использует контекст веб-браузера

Информация: 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);
            }
        }
    }
15 голосов
/ 29 июля 2011

Почему бы просто не обойти части обработки файлов 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");
    }
1 голос
/ 24 июля 2011

Ну, ваше решение почти работает.Чтобы упростить его, необходимо учитывать несколько моментов:

  • Отмените навигацию по умолчанию только для определенных URL-адресов, которые, как вы знаете, будут загружены, или пользователь не сможетперемещаться куда угодноЭто означает, что вы не должны изменять URL-адреса загрузки своего веб-сайта.

  • DownloadFileAsync не знает имя, указанное сервером в заголовке Content-Disposition, поэтому вы должны указать его,или вычислите один из исходного URL, если это возможно.Вы не можете просто указать папку и ожидать, что имя файла будет получено автоматически.

  • Вы должны обрабатывать ошибки сервера загрузки из обратного вызова DownloadCompleted, потому что управление веб-браузером не будетэто больше для вас.

Пример кода, который будет загружен в каталог, указанный в 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");
}

Это решение должно работать, но его очень легко сломать.Попробуйте рассмотреть некоторые веб-службы, перечисляющие доступные для загрузки файлы, и создайте для них пользовательский интерфейс.Это будет проще, и вы будете контролировать весь процесс.

0 голосов
/ 30 марта 2018

Гораздо более простым решением было бы загрузить файл с помощью 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");
        }
    }
}
0 голосов
/ 23 июля 2011

Взгляните на http://www.csharp -examples.net / download-files / и документы MSDN на веб-клиенте http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx

Я предлагаю попробовать синхронную загрузку, так как она более проста,Вы можете получить представление о том, являются ли параметры веб-клиента неправильными или файл имеет неправильный формат при попытке этого.

Вот пример кода ..

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