1、判断更新路径下是否有需要更新的版本;
2、将最新版本文件复制到当前路径的文件夹NewVersion下;
3、关闭当前程序,启动更新软件update.exe;
4、更新软件将NewVersion下的文件移到当前路径下进行覆盖;
5、完成更新操作,关闭update.exe,启动软件程序
准备条件:
1、更新文件放在以版本号命名的文件夹里,如:1.0.6.0;
2、设置共享文件夹,如//Server/VersionUpdate/,将版本文件夹放进去;
3、更新软件Update.exe,放到软件启动路径下。
在这里需要解决几个问题:
1、更新软件update.exe本身需要 更新;
2、版本更新跨越太大,漏掉一些必须更新文件,比如从1.0版直接升级到3.0版,就可能遗漏2.0版的文件;
3、更新文件中含有文件。
处理:1、可以在程序中先判断更新版本中有没有Update.exe,如果有就将其直接覆盖本地的Update.exe。其余继续复制到NewVersion下;
2、对于一些不进行升级就有遗漏的版本可以做个标记,更新时会对这些文件进行复制;
3、直接对更新文件下的文件夹也整个复制。
update.exe
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.IO; using System.Threading; using System.Diagnostics; namespace Update { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { try { Thread.Sleep(1000); //程序还在运行,等待关闭 ExeRun("Test", true); string path = Path.Combine(Application.StartupPath, "NewVersion"); if (Directory.Exists(path)) { RemoveDirectory(path, Application.StartupPath); if (File.Exists("Test.exe")) { Process.Start("Test.exe"); } } } catch (Exception ex) { MessageBox.Show("更新失败," + ex.Message); } } /// <summary> /// 程序运行监控 /// </summary> /// <param name="exe">程序名称</param> /// <param name="kill">是否强制关闭</param> private static void ExeRun(string exe,bool kill) { while (true) { Process[] ps = Process.GetProcessesByName(exe); if (ps.Length != 0) { if (kill) { foreach (Process p in ps) { p.Kill(); } } Thread.Sleep(1000); } else { break; } } } /// <summary> /// 转移文件夹 /// </summary> /// <param name="sourceDirName">源文件夹</param> /// <param name="destDirName">目标文件夹</param> public static void RemoveDirectory(string sourceDirName, string destDirName) { if (!Directory.Exists(destDirName)) { Directory.CreateDirectory(destDirName); } //判断路径后面有没有加/ if (destDirName[destDirName.Length - 1] != Path.DirectorySeparatorChar) destDirName = destDirName + Path.DirectorySeparatorChar; string[] files = Directory.GetFiles(sourceDirName); foreach (string file in files) { File.Copy(file, destDirName + Path.GetFileName(file), true); File.Delete(file); } string[] dirs = Directory.GetDirectories(sourceDirName); foreach (string dir in dirs) { RemoveDirectory(dir, destDirName + Path.GetFileName(dir)); Directory.Delete(dir); } } } }
软件Test.exe版本更新实现
public static bool VersionCheck(string updatePath) { try { string version = Application.ProductVersion.ToString(); if (!Directory.Exists("NewVersion")) { DirectoryInfo info = new DirectoryInfo("NewVersion"); info.Create(); } if (Directory.Exists(updatePath)) { return LocalNetUpdate( version, updatePath); } else { } } catch (Exception ex) { WriteLog(ex.Message); } return true; } private static bool LocalNetUpdate(string version, string updatePath) { DirectoryInfo dr = new DirectoryInfo(updatePath); //找到更新文件的路径,有“+”的必须进行更新 string[] dirs = dr.GetDirectories().Select(s => s.Name).ToArray(); //获取比当前版本高的版本路径 string[] findPath = dirs.Where(s => IsVersion(s) && s.CompareTo(version + "+") == 1).ToArray(); if (findPath.Length > 0) { //获取必须进行复制的文件版本 string[] superVer = findPath.Where(s => s.EndsWith(@"+")).ToArray(); Array.Sort(superVer); string target = findPath.Max(); if (MessageBox.Show("检测到有新版本" + target.Replace("+", "") + ",现在是否更新?", MessageBoxButtons.OKCancel) == DialogResult.OK) { try { foreach (string ver in superVer) { CopyDirectory(Path.Combine(updatePath, ver), "NewVersion", "Update.exe"); } if (!superVer.Contains(target)) { CopyDirectory(Path.Combine(updatePath, target), "NewVersion", "Update.exe"); } //保存更新记录 try { string txt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 用户: " + Environment.UserName + " 旧版本:" + version + " 升级:" + target; WriteToTxt(Path.Combine(updatePath, "updateLog.txt"), txt); } catch (Exception) { } if (File.Exists("Update.exe")) { Process.Start("Update.exe"); } System.Environment.Exit(0); } catch (Exception ex) { WriteLog(ex.Message); return false; } } else { } } else { } return true; } /// <summary> /// 判断字符串是否为版本号,后面加+的为特殊标记,如:1.0.4.0+ /// </summary> /// <param name="str"></param> /// <returns></returns> public static bool IsVersion(string str) { if (str == null) return false; return Regex.IsMatch(str, @"^\d+(\.\d+)+\+?$"); } /// <summary> /// 复制文件夹 /// </summary> /// <param name="sourceDirName">源文件夹</param> /// <param name="destDirName">目标文件夹</param> /// <param name="update">放到当前路径的文件名</param> public static void CopyDirectory(string sourceDirName, string destDirName, string update) { if (!Directory.Exists(destDirName)) { Directory.CreateDirectory(destDirName); } //判断路径后面有没有加/ if (destDirName[destDirName.Length - 1] != Path.DirectorySeparatorChar) destDirName = destDirName + Path.DirectorySeparatorChar; string[] files = Directory.GetFiles(sourceDirName); foreach (string file in files) { //如果是Update.exe则放到软件启动路径下 if (!string.IsNullOrEmpty(update) && Path.GetFileName(file) == update) { File.Copy(file, Path.GetFileName(file), true); } else { File.Copy(file, destDirName + Path.GetFileName(file), true); } } string[] dirs = Directory.GetDirectories(sourceDirName); foreach (string dir in dirs) { CopyDirectory(dir, destDirName + Path.GetFileName(dir), ""); } }