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