web-dev-qa-db-ja.com

ファイルをダウンロードして、フォルダーに自動的に保存します

サイトからファイルをダウンロードするための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

10

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

私のプログラムはあなたが望んでいることを正確に行います。プロンプトも何もありません。次のコードをご覧ください。

このコードは、必要なディレクトリがすべて存在しない場合は作成します。

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
    }

したがって、これらの2つのコードを使用して、すべてのディレクトリを作成し、ダウンローダーに指示することができます(その場所にファイルをダウンロードするよう求められません)。

20
user863551

「WebClient」を使用したくない場合、および/またはSystem.Windows.Forms.WebBrowserを使用する必要がある場合最初にログインをシミュレートするため、Windows URLMON Libから「URLDownloadToFile」メソッドをフックし、WebBrowserのコンテキストを使用するこの拡張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);
            }
        }
    }
18
dataCore

まあ、あなたのソリューションはほとんど動作します。シンプルにするために考慮すべきことがいくつかあります。

  • ダウンロードが発生することがわかっている特定のURLについてのみデフォルトのナビゲーションをキャンセルします。そうしないと、ユーザーはどこにもナビゲートできません。つまり、WebサイトのダウンロードURLを変更する必要はありません。

  • DownloadFileAsyncContent-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を作成してください。よりシンプルになり、プロセス全体を制御できます。

1

http://www.csharp-examples.net/download-files/ とwebclientのmsdn docsをご覧ください 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!");
}
0
Mulki

もっと簡単な解決策は、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");
        }
    }
}