using System; using System.Globalization; using System.IO; using System.Threading; namespace PCL.Core.App.Essentials; public static class UpdateHelper { /// /// 更新启动器(替换文件) /// /// 用于替换的来源文件路径 /// 目标文件路径 public static Exception? Replace(string source, string target) { var backup = $"{target}.bak.{DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture)}"; Exception? lastEx = null; try { source = Path.GetFullPath(source); target = Path.GetFullPath(target); // 备份目标文件 File.Copy(target, backup); if (!File.Exists(backup)) throw new FileNotFoundException("备份目标文件失败", backup); // 删除原文件并等待文件删除事件 var watcher = new FileSystemWatcher(Basics.GetParentPathOrEmpty(target), Path.GetFileName(target)); var deletedEvent = new ManualResetEventSlim(false); watcher.Deleted += (_, _) => deletedEvent.Set(); watcher.EnableRaisingEvents = true; File.Delete(target); if (!deletedEvent.Wait(TimeSpan.FromSeconds(3))) throw new TimeoutException("删除目标文件失败"); watcher.EnableRaisingEvents = false; watcher.Dispose(); // 复制到目标文件 File.Copy(source, target); if (!File.Exists(target)) throw new FileNotFoundException("复制到目标文件失败", target); } catch (Exception ex) { // 出错:恢复原文件并返回异常 if (File.Exists(backup) && !File.Exists(target)) File.Move(backup, target); lastEx = ex; } if (File.Exists(backup)) File.Delete(backup); // 删除备份文件 return lastEx; } }