web-dev-qa-db-fra.com

Télécharger le fichier et l'enregistrer automatiquement dans un dossier

J'essaie de créer une interface utilisateur pour télécharger des fichiers de mon site. Les fichiers Zip du site doivent être téléchargés dans le répertoire indiqué par l'utilisateur. Cependant, je ne peux pas réussir à télécharger le fichier, il s'ouvre simplement à partir d'un dossier temporaire.

Code:

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

Code source complet: http://fr.paidpaste.com/LqEmiQ

9
Victor Bjelkholm

Pourquoi ne pas simplement ignorer les éléments de gestion de fichiers du WebClient. Peut-être quelque chose de similaire à ceci:

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

Mon programme fait exactement ce que vous recherchez, aucune invite ou quoi que ce soit, veuillez consulter le code suivant.

Ce code créera tous les répertoires nécessaires s'ils n'existent pas déjà:

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

Ce code téléchargera le fichier donné dans le répertoire indiqué (après l'avoir créé avec l'extrait de code précédent:

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
    }

Donc, en utilisant ces deux morceaux de code, vous pouvez créer tous les répertoires puis dire au téléchargeur (cela ne vous invite pas à télécharger le fichier à cet emplacement.

19
user863551

Si vous ne souhaitez pas utiliser "WebClient" ou/et devez utiliser le System.Windows.Forms.WebBrowser, par ex. comme vous voulez d'abord simuler une connexion, vous pouvez utiliser ce navigateur Web étendu qui relie la méthode "URLDownloadToFile" à partir de la librairie Windows URLMON et utilise le contexte du navigateur Web

Infos: 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);
            }
        }
    }
16
dataCore

Eh bien, votre solution fonctionne presque. Il faut tenir compte de quelques éléments pour rester simple:

  • Annulez la navigation par défaut uniquement pour des URL spécifiques pour lesquelles un téléchargement aura lieu, sinon l'utilisateur ne pourra pas naviguer où que ce soit. Cela signifie que vous ne devez pas modifier les URL de téléchargement de votre site Web.

  • DownloadFileAsync ne connaît pas le nom indiqué par le serveur dans l'en-tête Content-Disposition. Vous devez donc en spécifier un ou en calculer un à partir de l'URL d'origine, si cela est possible. Vous ne pouvez pas simplement spécifier le dossier et attendre que le nom du fichier soit automatiquement récupéré.

  • Vous devez gérer les erreurs de serveur de téléchargement à partir du rappel DownloadCompleted car le contrôle du navigateur Web ne le fera plus pour vous.

Exemple de code à télécharger dans le répertoire spécifié dans textBox1, mais avec un nom de fichier aléatoire et sans autre traitement d'erreur:

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

Cette solution devrait fonctionner mais peut être cassée très facilement. Essayez d’envisager un service Web répertoriant les fichiers disponibles au téléchargement et de créer une interface utilisateur personnalisée. Ce sera plus simple et vous contrôlerez tout le processus.

1
Julien Lebosquain

Jetez un oeil à http://www.csharp-examples.net/download-files/ Et aux documents msdn sur le client Web. http://msdn.Microsoft.com/en-us/library/system.net.webclient.aspx

Ma suggestion est d'essayer le téléchargement synchrone comme son plus simple. Vous pourrez peut-être savoir si les paramètres du client Web sont incorrects ou si le fichier est au format incorrect.

Voici un exemple de code ..

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

Une solution beaucoup plus simple serait de télécharger le fichier avec Chrome. De cette manière, vous n'avez pas à cliquer manuellement sur le bouton Enregistrer. 

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