未涉及过winform升级,研究一阵,大致出来个不成熟的方案。
我的解决方案(判断升级,升级程序下载安装包的压缩包,解压,自动安装,重新启动程序)。
1、首先根据服务器中软件版本号和本地软件版本号是否一致,来确认程序是否需要升级。
1)本地可以用现成AssemblyInfo.cs文件中assembly: AssemblyVersion("1.0.0.0")来记录,通过反射来获取版本号:System.Reflection.Assembly.GetExecutingAssembly().GetName().Version。
2)需要升级启动升级程序Update.exe,并关闭主程序。
Process p = new Process(); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = fileName; p.StartInfo.CreateNoWindow = true; p.StartInfo.Arguments = versionInfo.Url;//判断是否需要升级时返回VersionInfo类型,包括新版本号和下载链接,传值给升级程序 p.Start(); System.Environment.Exit(System.Environment.ExitCode);
2、升级程序。
执行下载及解压,覆盖安装。
缺点:代码有待优化;
完全安装,耗时;
对网络有要求;、
本地数据库不能保留原有数据。
//升级程序接收参数 static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FMUpdate(args)); } } private string _url; public FMUpdate(string[] args) { InitializeComponent(); _url = args[0]; }
private void FMUpdate_Load(object sender, EventArgs e) { WebClient wc = new WebClient(); wc.DownloadProgressChanged += wc_DownloadProgressChanged; wc.DownloadFileAsync(new Uri(_url), @"c:update.rar"); }
private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { Action act = () => { this.progressBar1.Value = e.ProgressPercentage; this.lblTip.Text = "正在下载..."; //this.label1.Text = e.ProgressPercentage + "%"; }; this.Invoke(act); if (e.ProgressPercentage == 100) { //下载完成之后开始覆盖 this.lblTip.Text = "正在解压..."; try { var result = CompressHelper.Uncompress(@"c:update.rar", “解压路径”); if (result) { progressBar1.Value = 110; this.lblTip.Text = "准备安装..."; //备份之前数据库 var dbFile = Application.StartupPath + "/db/数据库文件.db"; if (File.Exists(dbFile)) { var bakFile = Application.StartupPath + "/backup/" + DateTime.Now.ToString("yyyyMMddHHmmssms") + ".bak"; var bakDirectory = Path.GetDirectoryName(bakFile); DirectoryInfo directoryInfo = new DirectoryInfo(bakDirectory); if (!directoryInfo.Exists) { directoryInfo.Create(); } else { //删除7天前的备份文件 var files = directoryInfo.GetFiles(); if (files != null && files.Length > 0) { foreach (var file in files) { if (file.CreationTime.AddDays(7) < DateTime.Now) { file.Delete(); } } } } //备份文件 File.Move(dbFile, bakFile); } this.lblTip.Text = "准备安装"; Install(); this.lblTip.Text = "安装完成"; var mainFile = Application.StartupPath + @"Main.exe"; Process p = new Process(); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = mainFile; p.StartInfo.CreateNoWindow = true; p.Start(); this.Close(); } else { MessageBox.Show("更新失败"); this.Close(); } } catch (Exception ex) { MessageBox.Show("更新失败", ex.Message); this.Close(); } } } private void Install() { try { Process p = new Process(); p.StartInfo.FileName = "msiexec.exe"; p.StartInfo.Arguments = $"/i {_temp}利万嘉收银系统安装文件.msi /qb-!";// /qb显示基本界面 /qb-!或者/qb!- 基本界面无取消按钮 p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.Start(); p.WaitForExit(); p.Close(); } catch (Exception ex) { MessageBox.Show("更新失败:" + ex.Message); } }
再说下关于增量升级。
1、单独升级站点,保存项目的资源文件、程序集等。
2、xml记录版本及更新的文件。
3、启动升级程序,从升级站点直接拷贝修改的文件、程序集。
遗留问题:
1、增量升级跨多个版本,升级xml每个版本都记录?
2、两种方案对数据库操作,执行数据库脚本?如何执行?
求见解。。。。。。