2011-07-21 13 views
9

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

+1

のポスト関連部品:あなたが最初のログインをシミュレートするには、Windows URLMONのLibから「URLDownloadToFile」メソッドをフックし、Webブラウザー

に関する情報のコンテキストを使用して、この拡張されたWebブラウザーを使用することができますしたいので、あなたのコードは、ここでは、直接の質問です。外部リンクを使用しないでください。 –

+0

@アンダーアベル、修正済み! –

+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

は、Webクライアント上http://www.csharp-examples.net/download-files/ とMSDNドキュメントを見てみましょう 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

問題は、Webブラウザで動作するInternet Explorerではなく、アプリケーションでファイルをダウンロードすることです。 zipファイルのリンクをクリックすると、保存ファイルのポップアップが表示され、私は物事を選択してほしい。ユーザーがzipをクリックしたときにファイルが自動的にダウンロードされるようにしたい。 –

+0

@Victor:まあ、....私は完全に質問を誤解した。 変更の回答 – Mulki

0

さて、あなたのソリューションはほとんど機能します。それをシンプルに保つために考慮に入れるべき点がいくつかあります。

  • はあなたがダウンロードが発生します知っている特定のURLのためにデフォルトのナビゲーションをキャンセル、またはユーザーが任意の場所に移動することはできません。これはあなたのウェブサイトのダウンロードURLを変更しないことを意味します。

  • DownloadFileAsyncは、Content-Dispositionヘッダーのサーバーによって報告された名前を認識できないため、1つを指定するか、元の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"); 
} 

このソリューションが動作するはずですが、することができ非常に簡単に壊れました。利用可能なファイルをダウンロードしてカスタムUIを作成するWebサービスを検討してみてください。それはより簡単になり、プロセス全体を制御します。

+0

私はまた、カスタムUIを作成しようとしましたが、成功しませんでした。まだ非常に基本的なレベルで学習し、常に立ち往生してください。しかし、あなたの時間と助けてくれてありがとう、私は状態の更新で戻ってきます。 –

+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 

このコードは前のスニペットによって作成された後に(与えられたディレクトリに指定したファイルをダウンロードします。

ですから、すべてのディレクトリを作成し、その場所にファイルをダウンロードするようにプロンプ​​トを表示しませんダウンローダを(言うことができるコードのこれら2つを使用して
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を使用する必要がない場合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を返しました。 –

関連する問題