我正在尝试创建一个用于从我的网站下载文件的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);
}
答案 0 :(得分:19)
我的程序完全符合您的要求,没有任何提示或任何内容,请参阅以下代码。
如果这些代码尚不存在,则此代码将创建所有必需的目录:
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
}
因此,使用这两段代码,您可以创建所有目录,然后告诉下载程序(不会提示您将文件下载到该位置。
答案 1 :(得分:16)
如果您不想使用" WebClient"或/并且需要使用System.Windows.Forms.WebBrowser,例如因为你想首先模拟一个登录,你可以使用这个扩展的WebBrowser挂钩" URLDownloadToFile" Windows URLMON Lib中的方法并使用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 :(得分:14)
为什么不完全绕过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");
}
答案 3 :(得分:1)
嗯,你的解决方案几乎可行。为了简单起见,有几点需要考虑:
仅针对您知道会发生下载的特定网址取消默认导航,否则用户将无法在任何位置导航。这意味着您不会更改您的网站下载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");
}
这个解决方案应该可行,但可以很容易地解决。尝试考虑列出可供下载的可用文件的一些Web服务,并为其创建自定义UI。它会更简单,你将控制整个过程。
答案 4 :(得分:0)
看看http://www.csharp-examples.net/download-files/ 和webclient上的msdn文档 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!");
}
答案 5 :(得分:0)
更简单的解决方案是使用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");
}
}
}