越来越多的客户端安装桌面程序,如何让程序保持最新版本实现自动更新成为一个问题。
思路:
客户端程序增加自动功能,调用自动更新程序,透过http或者ftp下载到客户端进行替换。由于时间比较急没有采用http下载压缩包到客户端进行解压实现,直接通过架设ftp服务器下载替换(最好是结合xml进行比对哪些程序需要更新),本次直接更
新。
(1)新建ftp服务器
(2) 主程序调用,调用时关闭主线程
(3)自动下载更新
private void btnUpdate_Click(object sender, EventArgs e)
{
try
{
if (MessageBox.Show("检查到新版本,是否更新?", "更新", MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
{
//更新(调用更新的exe,这个是单独的一个程序,下面再说怎么写)
string fileName = Application.StartupPath + @"\DZAMSUpdate.exe";
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = fileName;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.Arguments = "你好, 厦门欢迎你!";//参数以空格分隔,如果某个参数为空,可以传入””
p.Start();
System.Environment.Exit(System.Environment.ExitCode); //结束主线程
// p.WaitForExit(); //这里就不能等他结束了
// string output = p.StandardOutput.ReadToEnd(); //this.Dispose();//关闭主程序
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
FtpHelper.cs
static public class FtpHelper
{
//基本设置
static private string path = @"ftp://" + Helper.GetAppConfig("obj") + "/"; //目标路径
static private string ftpip = Helper.GetAppConfig("obj"); //ftp IP地址
static private string username = Helper.GetAppConfig("username"); //ftp用户名
static private string password = Helper.GetAppConfig("password"); //ftp密码
//获取ftp上面的文件和文件夹
public static string[] GetFileList(string dir)
{
string[] downloadFiles;
StringBuilder result = new StringBuilder();
FtpWebRequest request;
try
{
request = (FtpWebRequest)FtpWebRequest.Create(new Uri(path));
request.UseBinary = true;
request.Credentials = new NetworkCredential(username, password);//设置用户名和密码
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.UseBinary = true;
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
Console.WriteLine(line);
line = reader.ReadLine();
}
// to remove the trailing '\n'
result.Remove(result.ToString().LastIndexOf('\n'), 1);
reader.Close();
response.Close();
return result.ToString().Split('\n');
}
catch (Exception ex)
{
Console.WriteLine("获取ftp上面的文件和文件夹:" + ex.Message);
downloadFiles = null;
return downloadFiles;
}
}
/// <summary>
/// 获取文件大小
/// </summary>
/// <param name="file">ip服务器下的相对路径</param>
/// <returns>文件大小</returns>
public static int GetFileSize(string file,string Dir)
{
StringBuilder result = new StringBuilder();
FtpWebRequest request;
try
{
request = (FtpWebRequest)FtpWebRequest.Create(new Uri(path+ "\\" + Dir + "\\" + file));
request.UseBinary = true;
request.Credentials = new NetworkCredential(username, password);//设置用户名和密码
request.Method = WebRequestMethods.Ftp.GetFileSize;
int dataLength = (int)request.GetResponse().ContentLength;
return dataLength;
}
catch (Exception ex)
{
Console.WriteLine("获取文件大小出错:" + ex.Message);
return -1;
}
}
/// <summary>
/// 文件上传
/// </summary>
/// <param name="filePath">原路径(绝对路径)包括文件名</param>
/// <param name="objPath">目标文件夹:服务器下的相对路径 不填为根目录</param>
public static void FileUpLoad(string filePath, string objPath = "")
{
try
{
string url = path;
if (objPath != "")
url += objPath + "/";
try
{
FtpWebRequest reqFTP = null;
//待上传的文件 (全路径)
try
{
FileInfo fileInfo = new FileInfo(filePath);
using (FileStream fs = fileInfo.OpenRead())
{
long length = fs.Length;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(url + fileInfo.Name));
//设置连接到FTP的帐号密码
reqFTP.Credentials = new NetworkCredential(username, password);
//设置请求完成后是否保持连接
reqFTP.KeepAlive = false;
//指定执行命令
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
//指定数据传输类型
reqFTP.UseBinary = true;
using (Stream stream = reqFTP.GetRequestStream())
{
//设置缓冲大小
int BufferLength = 5120;
byte[] b = new byte[BufferLength];
int i;
while ((i = fs.Read(b, 0, BufferLength)) > 0)
{
stream.Write(b, 0, i);
}
Console.WriteLine("上传文件成功");
}
}
}
catch (Exception ex)
{
Console.WriteLine("上传文件失败错误为" + ex.Message);
}
finally
{
}
}
catch (Exception ex)
{
Console.WriteLine("上传文件失败错误为" + ex.Message);
}
finally
{
}
}
catch (Exception ex)
{
Console.WriteLine("上传文件失败错误为" + ex.Message);
}
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="fileName">服务器下的相对路径 包括文件名</param>
public static void DeleteFileName(string fileName)
{
try
{
FileInfo fileInf = new FileInfo(ftpip + "" + fileName);
string uri = path + fileName;
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
// 指定数据传输类型
reqFTP.UseBinary = true;
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(username, password);
// 默认为true,连接不会被关闭
// 在一个命令之后被执行
reqFTP.KeepAlive = false;
// 指定执行什么命令
reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
response.Close();
}
catch (Exception ex)
{
Console.WriteLine("删除文件出错:" + ex.Message);
}
}
/// <summary>
/// 新建目录 上一级必须先存在
/// </summary>
/// <param name="dirName">服务器下的相对路径</param>
public static void MakeDir(string dirName)
{
try
{
string uri = path + dirName;
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
// 指定数据传输类型
reqFTP.UseBinary = true;
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
response.Close();
}
catch (Exception ex)
{
Console.WriteLine("创建目录出错:" + ex.Message);
}
}
/// <summary>
/// 删除目录 上一级必须先存在
/// </summary>
/// <param name="dirName">服务器下的相对路径</param>
public static void DelDir(string dirName)
{
try
{
string uri = path + dirName;
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.RemoveDirectory;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
response.Close();
}
catch (Exception ex)
{
Console.WriteLine("删除目录出错:" + ex.Message);
}
}
/// <summary>
/// 从ftp服务器上获得文件夹列表
/// </summary>
/// <param name="RequedstPath">服务器下的相对路径</param>
/// <returns></returns>
public static List<string> GetDirctory(string RequedstPath)
{
List<string> strs = new List<string>();
try
{
string uri = path + RequedstPath; //目标路径 path为服务器地址
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
WebResponse response = reqFTP.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());//中文文件名
string line = reader.ReadLine();
while (line != null)
{
if (line.Contains("<DIR>"))
{
string msg = line.Substring(line.LastIndexOf("<DIR>") + 5).Trim();
strs.Add(msg);
}
line = reader.ReadLine();
}
reader.Close();
response.Close();
return strs;
}
catch (Exception ex)
{
Console.WriteLine("获取目录出错:" + ex.Message);
}
return strs;
}
/// <summary>
/// 从ftp服务器上获得文件列表
/// </summary>
/// <param name="RequedstPath">服务器下的相对路径</param>
/// <returns></returns>
public static List<string> GetFile(string RequedstPath)
{
List<string> strs = new List<string>();
try
{
string uri = path + RequedstPath; //目标路径 path为服务器地址
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
// ftp用户名和密码
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
WebResponse response = reqFTP.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());//中文文件名
string line = reader.ReadLine();
while (line != null)
{
if (!line.Contains("<DIR>"))
{
string msg = line.Substring(39).Trim();
strs.Add(msg);
}
line = reader.ReadLine();
}
reader.Close();
response.Close();
return strs;
}
catch (Exception ex)
{
Console.WriteLine("获取文件出错:" + ex.Message);
}
return strs;
}
//从ftp服务器上下载文件的功能
public static void Download(string fileName,string Dir,string pathLocal)
{
string filePath = pathLocal; //Application.StartupPath;
FtpWebRequest reqFTP;
try
{
FileStream outputStream = new FileStream(filePath + fileName, FileMode.Create);//本地路径
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(path + "\\" + Dir+"\\"+ fileName)); //ftp路径
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
// 指定数据传输类型
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.UsePassive = true;
reqFTP.KeepAlive = true;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
// 服务器文件的大小
long cl = response.ContentLength;
// 缓冲大小设置为2kb
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
}
ftpStream.Close();
outputStream.Close();
response.Close();
}
catch (Exception ex)
{
throw ex;
}
}
}
更新窗体
public partial class Update_Frm : Form
{
//文件下载会自动覆盖原文件,无需删除
public static string UrlLocal = "D:\\DZAMS\\Debug\\";
public static string DirDZAMS = "DZAMS\\Debug";
int fileCount;
public Update_Frm()
{
InitializeComponent();
this.Width = 600;
this.Height = 175;
this.MaximizeBox = false;
this.MinimizeBox = false;
}
private void Update_Frm_Load(object sender, EventArgs e)
{
//关闭已经启动进程DZAMS
Process[] pa = Process.GetProcesses();//获取当前进程数组。
foreach (Process p in pa)
{
if (p.ProcessName == "DZAMS")
{
p.Kill();
}
}
//创建目录先
CreateDir();
}
/// <summary>
/// 更新一级目录与二级目录文件夹
/// </summary>
public void CreateDir()
{
if (!Directory.Exists(UrlLocal)) //目标文件夹是否存在
{
Directory.CreateDirectory(UrlLocal);
lblFileMsg.Text = "正在创建文件夹:" + UrlLocal;
}
else
{
List<string> Dir = new List<string>();
Dir = FtpHelper.GetDirctory(DirDZAMS);
//遍历FTP服务器文件夹并更新到本地
foreach (string dir in Dir)
{
if (Directory.Exists(UrlLocal + dir))
{
// DeleteFile(UrlLocal + dir);
}
else
{
Directory.CreateDirectory(UrlLocal + dir);
lblFileMsg.Text = "正在创建文件夹:" + UrlLocal + dir;
}
}
}
}
/// <summary>
/// 从FTP服务器下载文件
/// </summary>
public void SyncAllFile()
{
//SyncDirFile();
/*
List<string> Dir = new List<string>();
Dir = FtpHelper.GetDirctory(DirDZAMS);
//遍历FTP服务器文件夹并更新到本地
foreach (string dir in Dir)
{
//if (Directory.Exists(UrlLocal + dir))
//{
// DeleteFile(UrlLocal + dir);
//}
//else
//{
// Directory.CreateDirectory(UrlLocal + dir);
//}
//遍历FTP服务器文件并更新到本地
List<string> File2 = new List<string>();
File2 = FtpHelper.GetFile(DirDZAMS + "\\" + dir);//获取FTP二级目录文件
foreach (string file in File2)
{
////判断本地文件是否存在,则比对本地文件的
//if (File.Exists(UrlLocal + "\\" + dir + "\\" + file))
//{
// DeleteFile(UrlLocal + "\\" + dir + "\\" + file);
// //FileInfo f1 = new FileInfo(UrlLocal + "\\" + dir + "\\" + file);
// //if (DateTime.Compare(FtpHelper.GetCreateTime(file, DirDZAMS + "\\" + dir), f1.CreationTime) > 0)
// //{
// //}
//}
lblFileMsg.Text = "正在更新文件:" + "\\" + dir + "\\" + file;
FtpHelper.Download(file, DirDZAMS + "\\" + dir, UrlLocal + dir + "\\");
fileCount++;
}
}
*/
//遍历FTP服务器文件并更新到本地
List<string> MyFile = new List<string>();
MyFile = FtpHelper.GetFile(DirDZAMS);//获取FTP服务器文件
foreach (string file in MyFile)
{
//判断本地文件是否存在,存在删除
//if (File.Exists(UrlLocal+file))
//{
// DeleteFile(UrlLocal + file);
//}
FtpHelper.Download(file, DirDZAMS, UrlLocal);
lblFileMsg.Text = "正在更新文件:" + "\\" + DirDZAMS + "\\" + file;
fileCount++;
}
}
public void SyncDirFile()
{
List<string> Dir = new List<string>();
Dir = FtpHelper.GetDirctory(DirDZAMS);
//遍历FTP服务器文件夹并更新到本地
foreach (string dir in Dir)
{
List<string> File2 = new List<string>();
File2 = FtpHelper.GetFile(DirDZAMS + "\\" + dir);//获取FTP二级目录文件
foreach (string file in File2)
{
lblFileMsg.Text = "正在更新文件:" + "\\" + dir + "\\" + file;
FtpHelper.Download(file, DirDZAMS + "\\" + dir, UrlLocal + dir + "\\");
fileCount++;
}
}
lblMsg.Text = "更新完成:总共 " + fileCount.ToString() + "个文件";
}
/// <summary>
/// 根据路径删除文件
/// </summary>
/// <param name="path"></param>
public void DeleteFile(string path)
{
FileAttributes attr = File.GetAttributes(path);
if (attr == FileAttributes.Directory)
{
Directory.Delete(path, true);
}
else
{
File.Delete(path);
}
}
private void BtnUpdate_Click(object sender, EventArgs e)
{
this.BtnUpdate.Enabled = false;
//更新文件
SyncAllFile();
MessageBox.Show("程序已更新,更新完成时间:" + System.DateTime.Now.ToLongTimeString());
System.Environment.Exit(0);
}
}