/// <summary> /// 根据指定文件夹中的文件信息并在此文件夹下输出自动更新的XML文件。 /// </summary> /// <param name="dir">指定文件夹。</param> /// <param name="fileName">自动更新的文件名。</param> public static void Write(string dir, string fileName) { AutoUpdateXmlFile au = Get(dir); //根据文件格式生成XML文件。 XmlSerializer serializer = new XmlSerializer(typeof(AutoUpdateXmlFile)); using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)) { serializer.Serialize(stream, au); } }
/// <summary> /// 根据指定文件夹中的文件信息获取自动更新的XML文件类。 /// </summary> /// <param name="dir">指定文件夹。</param> public static AutoUpdateXmlFile Get(string dir) { //获取指定目录下的所有文件。 string[] files = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories); AutoUpdateXmlFile au = new AutoUpdateXmlFile(); foreach (string file in files) { //忽略指定文件。 string relativePath = file.Replace(dir, "").TrimStart('\\'); Console.WriteLine(string.Format("检测本地文件:{0}", relativePath)); if (CheckIsIgnoreFile(relativePath)) { continue; } //添加需要自动更新的文件。 FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(file); AutoUpdateItem item = new AutoUpdateItem(); item.LastestModifyTime = File.GetLastWriteTime(file); item.RelativePath = relativePath; item.Name = versionInfo.OriginalFilename; item.Version = versionInfo.FileVersion; item.Description = versionInfo.FileDescription; item.Product = versionInfo.ProductName; item.Company = versionInfo.CompanyName; FileInfo fileInfo = new FileInfo(file); item.Size = fileInfo.Length; string extendName = Path.GetExtension(file); if (extendName.ToLower() == ".dll" || extendName.ToLower() == ".exe") { au.Assemblies.Add(item); } else { au.Files.Add(item); } } return(au); }
static int Main(string[] args) { string exeDir = Path.GetDirectoryName(typeof(Program).Assembly.Location); bool createdNew; using (Mutex mutex = new Mutex(true, "AutoUpdate" + exeDir.GetHashCode(), out createdNew)) { if (!createdNew) { // multiple calls in parallel? // it's sufficient to let one call run, so just wait for the other call to finish try { mutex.WaitOne(10000); } catch (AbandonedMutexException) { } return(0); } bool bOnlyOutput = false; string curDir = string.Empty; string baseUrl = string.Empty; string xmlName = "autoupdate.xml"; int exitCode = 0; try { for (int i = 0; i < args.Length; i++) { if (args[i] == "--workdirectory" && i + 1 < args.Length && !string.IsNullOrEmpty(args[i + 1])) { curDir = args[i + 1]; } else if (args[i] == "/o") { bOnlyOutput = true; } else if (args[i] == "--baseurl" && i + 1 < args.Length && !string.IsNullOrEmpty(args[i + 1])) { baseUrl = args[i + 1]; } else if (args[i] == "--xmlname" && i + 1 < args.Length && !string.IsNullOrEmpty(args[i + 1])) { xmlName = args[i + 1]; } } xmlName = "autoupdate.xml"; Console.WriteLine("开始更新:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); //如果没有设置工作文件夹 if (string.IsNullOrEmpty(curDir)) { curDir = Directory.GetCurrentDirectory(); } else { curDir = Path.GetFullPath(curDir); Directory.SetCurrentDirectory(curDir); } //仅输出自动更行XML文件。 if (bOnlyOutput) { AutoUpdateXmlSerializerUtil.Write(curDir, xmlName); return(exitCode); } AutoUpdater updater = new AutoUpdater(curDir, baseUrl); AutoUpdateXmlFile oldFile = AutoUpdateXmlSerializerUtil.Get(curDir); Console.WriteLine("正在连接服务器..."); updater.DownloadFile(xmlName); AutoUpdateXmlFile newFile = AutoUpdateXmlSerializerUtil.Read(curDir, xmlName); if (updater.Update(newFile, oldFile)) { Console.WriteLine("更新成功。" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); } else { Console.WriteLine("更新失败。" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); exitCode = 1; } } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine("更新失败。" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); exitCode = 2; } return(exitCode); } }
/// <summary> /// 自动更新文件。对比文件判断是否需要自动更新。 /// </summary> /// <param name="newFile">新文件。</param> /// <param name="oldFile">旧文件。</param> /// <returns>更新成功,true。更新失败,false。</returns> public bool Update(AutoUpdateXmlFile newFile, AutoUpdateXmlFile oldFile) { bool bSuccess = true; if (newFile == null || oldFile == null) { bSuccess = false; return(bSuccess); } Dictionary <AutoUpdateItem, EnumAutoUpdateAction> updateItems = new Dictionary <AutoUpdateItem, EnumAutoUpdateAction>(); #region 检查程序集 Console.WriteLine("正在检查需要更新的程序集..."); foreach (AutoUpdateItem oldItem in oldFile.Assemblies) { bool bMatch = false; bool bIsExits = false; foreach (AutoUpdateItem newItem in newFile.Assemblies) { if (newItem.RelativePath == oldItem.RelativePath) { bIsExits = true; string oldItemVersion = oldItem.Version ?? string.Empty; string newItemVersion = newItem.Version ?? string.Empty; if (oldItemVersion == newItemVersion && oldItem.Size == newItem.Size) { bMatch = true; } break; } } if (!bIsExits) { //updateItems.Add(oldItem, EnumAutoUpdateAction.Delete); } else if (!bMatch) { updateItems.Add(oldItem, EnumAutoUpdateAction.Update); } } foreach (AutoUpdateItem newItem in newFile.Assemblies) { bool bIsExits = false; foreach (AutoUpdateItem oldItem in oldFile.Assemblies) { if (newItem.RelativePath == oldItem.RelativePath) { bIsExits = true; break; } } if (!bIsExits) { updateItems.Add(newItem, EnumAutoUpdateAction.Add); } } #endregion #region 检查文件 Console.WriteLine("正在检查需要更新的文件..."); foreach (AutoUpdateItem oldItem in oldFile.Files) { bool bMatch = false; bool bIsExits = false; foreach (AutoUpdateItem newItem in newFile.Files) { if (newItem.RelativePath == oldItem.RelativePath) { bIsExits = true; string oldItemVersion = oldItem.Version ?? string.Empty; string newItemVersion = newItem.Version ?? string.Empty; if (oldItemVersion == newItemVersion && oldItem.Size == newItem.Size) { bMatch = true; if (oldItem.LastestModifyTime < newItem.LastestModifyTime) { bMatch = false; } } break; } } if (!bIsExits) { //updateItems.Add(oldItem, EnumAutoUpdateAction.Delete); } else if (!bMatch) { updateItems.Add(oldItem, EnumAutoUpdateAction.Update); } } foreach (AutoUpdateItem newItem in newFile.Files) { bool bIsExits = false; foreach (AutoUpdateItem oldItem in oldFile.Files) { if (newItem.RelativePath == oldItem.RelativePath) { bIsExits = true; break; } } if (!bIsExits) { updateItems.Add(newItem, EnumAutoUpdateAction.Add); } } #endregion foreach (AutoUpdateItem item in updateItems.Keys) { EnumAutoUpdateAction action = updateItems[item]; if (action == EnumAutoUpdateAction.Add || action == EnumAutoUpdateAction.Update) { Console.WriteLine("正在更新:" + item.RelativePath); if (!DownloadFile(item.RelativePath) && bSuccess) { bSuccess = false; } } } return(bSuccess); }