基于 WebClient 的 C# 启动器
C# Launcher based on WebClient
我正在为我的其他应用程序创建简单的启动器,我需要有关程序逻辑部分的建议。启动器需要检查连接,然后检查文件版本(从站点),将其与当前下载的版本(如果有)进行比较,如果一切正常,启动程序,如果没有,更新(下载)与最新版本不同的文件.这些文件是:
program.exe, config.cfg and mapFolder
。 program.exe
和mapFolder
必须更新,config.cfg
只有在没有该文件时才会下载。另外 mapFolder
是一个包含大量随机文件的文件夹(每个新版本在 mapFolder
中可能有完全不同的文件)。
对于文件版本,我想我会使用来自我的主站点的简单 DownloadString,它可能包含类似 program:6.0,map:2.3
的内容,所以最新的程序版本是 6.0,mapFolder 是 2.3。然后我可以使用 FileVersionInfo.GetVersionInfo
获取当前 program
的版本(如果有)并将文件 "version" 包含到 mapFolder
中以读取当前版本。
问题是我不知道如何使用 WebClient 下载整个文件夹,也不知道什么是完成我想做的事情的最佳方式。我尝试将 mapFolder
下载为 zip,然后自动解压,但启动器需要在 .net 3.0
.
中编码
这是我目前的代码,这只是一个原型,用于熟悉整个情况,不要基于它。
`
WebClient wc = new WebClient();
string verifySite = "google.com/downloads/version";
string downloadSite = "google.com/downloads/program.exe";
Uri verifyUri, downloadUri = null;
string userVer, currVer = "";
string downloadPath = Directory.GetCurrentDirectory();
string clientName = "program.exe";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(FileDownloaded);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileDownloadProgress);
chckAutorun.Checked = Properties.Settings.Default.autorun;
checkConnection();
if(!checkVersion())
downloadClient();
else
{
pbDownload.Value = 100;
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
}
private bool checkConnection()
{
verifyUri = new Uri("http://" + verifySite);
downloadUri = new Uri("http://" + downloadSite);
WebRequest req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
verifyUri = new Uri("https://" + verifySite);
downloadUri = new Uri("https://" + downloadUri);
req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
return false;
}
private void downloadClient()
{
try
{
wc.DownloadFileAsync(downloadUri, Path.Combine(downloadPath, clientName));
}
catch { }
}
private bool checkVersion()
{
lblProgress.Text = "checking for updates";
try
{
currVer = FileVersionInfo.GetVersionInfo(Path.Combine(downloadPath, clientName)).FileVersion;
}
catch {
currVer = "";
}
try
{
userVer = wc.DownloadString(verifyUri);
}
catch {
userVer = "";
}
return currVer == userVer && currVer != "";
}
private void FileDownloaded(object sender, AsyncCompletedEventArgs e)
{
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
private void FileDownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
long received = e.BytesReceived / 1000;
long toReceive = e.TotalBytesToReceive / 1000;
lblProgress.Text = string.Format("{0}KB {1}/ {2}KB", received, Repeat(" ", Math.Abs(-5 + Math.Min(5, received.ToString().Length))*2), toReceive);
pbDownload.Value = e.ProgressPercentage;
}
private void btnPlay_Click(object sender, EventArgs e)
{
btnPlay.Enabled = false;
if(checkVersion())
{
lblProgress.Text = "Starting...";
Process.Start(Path.Combine(downloadPath, clientName));
this.Close();
}
else
{
downloadClient();
}
}
public static string Repeat(string instr, int n)
{
if (string.IsNullOrEmpty(instr))
return instr;
var result = new StringBuilder(instr.Length * n);
return result.Insert(0, instr, n).ToString();
}
private void chckAutorun_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.autorun = chckAutorun.Checked;
Properties.Settings.Default.Save();
}`
我通过在 Web 服务器上启用 autoindex
并在以 .map 结尾的文件夹中下载文件字符串,设法实现了我的需要。
string mapSite = wc.DownloadString(new Uri("http://" + mapsSite));
maps = Regex.Matches(mapSite, "<a href=\"(.*).map\">");
foreach (Match m in maps)
{
string mapName = m.Value.Remove(0, 9).Remove(m.Length - 11);
downloaded = false;
wc.DownloadFileAsync(new Uri("http://" + mapsSite + mapName), Path.Combine(downloadPath, @"mapFolder/" + mapName));
while (!downloaded) { }
}
我正在为我的其他应用程序创建简单的启动器,我需要有关程序逻辑部分的建议。启动器需要检查连接,然后检查文件版本(从站点),将其与当前下载的版本(如果有)进行比较,如果一切正常,启动程序,如果没有,更新(下载)与最新版本不同的文件.这些文件是:
program.exe, config.cfg and mapFolder
。 program.exe
和mapFolder
必须更新,config.cfg
只有在没有该文件时才会下载。另外 mapFolder
是一个包含大量随机文件的文件夹(每个新版本在 mapFolder
中可能有完全不同的文件)。
对于文件版本,我想我会使用来自我的主站点的简单 DownloadString,它可能包含类似 program:6.0,map:2.3
的内容,所以最新的程序版本是 6.0,mapFolder 是 2.3。然后我可以使用 FileVersionInfo.GetVersionInfo
获取当前 program
的版本(如果有)并将文件 "version" 包含到 mapFolder
中以读取当前版本。
问题是我不知道如何使用 WebClient 下载整个文件夹,也不知道什么是完成我想做的事情的最佳方式。我尝试将 mapFolder
下载为 zip,然后自动解压,但启动器需要在 .net 3.0
.
这是我目前的代码,这只是一个原型,用于熟悉整个情况,不要基于它。 `
WebClient wc = new WebClient();
string verifySite = "google.com/downloads/version";
string downloadSite = "google.com/downloads/program.exe";
Uri verifyUri, downloadUri = null;
string userVer, currVer = "";
string downloadPath = Directory.GetCurrentDirectory();
string clientName = "program.exe";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(FileDownloaded);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileDownloadProgress);
chckAutorun.Checked = Properties.Settings.Default.autorun;
checkConnection();
if(!checkVersion())
downloadClient();
else
{
pbDownload.Value = 100;
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
}
private bool checkConnection()
{
verifyUri = new Uri("http://" + verifySite);
downloadUri = new Uri("http://" + downloadSite);
WebRequest req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
verifyUri = new Uri("https://" + verifySite);
downloadUri = new Uri("https://" + downloadUri);
req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
return false;
}
private void downloadClient()
{
try
{
wc.DownloadFileAsync(downloadUri, Path.Combine(downloadPath, clientName));
}
catch { }
}
private bool checkVersion()
{
lblProgress.Text = "checking for updates";
try
{
currVer = FileVersionInfo.GetVersionInfo(Path.Combine(downloadPath, clientName)).FileVersion;
}
catch {
currVer = "";
}
try
{
userVer = wc.DownloadString(verifyUri);
}
catch {
userVer = "";
}
return currVer == userVer && currVer != "";
}
private void FileDownloaded(object sender, AsyncCompletedEventArgs e)
{
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
private void FileDownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
long received = e.BytesReceived / 1000;
long toReceive = e.TotalBytesToReceive / 1000;
lblProgress.Text = string.Format("{0}KB {1}/ {2}KB", received, Repeat(" ", Math.Abs(-5 + Math.Min(5, received.ToString().Length))*2), toReceive);
pbDownload.Value = e.ProgressPercentage;
}
private void btnPlay_Click(object sender, EventArgs e)
{
btnPlay.Enabled = false;
if(checkVersion())
{
lblProgress.Text = "Starting...";
Process.Start(Path.Combine(downloadPath, clientName));
this.Close();
}
else
{
downloadClient();
}
}
public static string Repeat(string instr, int n)
{
if (string.IsNullOrEmpty(instr))
return instr;
var result = new StringBuilder(instr.Length * n);
return result.Insert(0, instr, n).ToString();
}
private void chckAutorun_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.autorun = chckAutorun.Checked;
Properties.Settings.Default.Save();
}`
我通过在 Web 服务器上启用 autoindex
并在以 .map 结尾的文件夹中下载文件字符串,设法实现了我的需要。
string mapSite = wc.DownloadString(new Uri("http://" + mapsSite));
maps = Regex.Matches(mapSite, "<a href=\"(.*).map\">");
foreach (Match m in maps)
{
string mapName = m.Value.Remove(0, 9).Remove(m.Length - 11);
downloaded = false;
wc.DownloadFileAsync(new Uri("http://" + mapsSite + mapName), Path.Combine(downloadPath, @"mapFolder/" + mapName));
while (!downloaded) { }
}