public void Rollback() { if (File.Exists(LogPath)) { var updater = new UpdaterLog(LogPath, false); updater.Revert(); } }
public async Task ApplyPatch(VersionModel patchInfo) { try { CurrentState = UpdateState.DownloadingPatch; OnUpdateProgress(new UpdateProgressModel { State = CurrentState, TotalBytes = 1, CompletedBytes = 0 }); if (!_updateFilesDir.Exists) { _updateFilesDir.Create(); } else { _updateFilesDir.Delete(true); _updateFilesDir.Create(); } var patchZipFile = new FileInfo(_updateFilesDir + "\\patch.zip"); var extractedDir = new DirectoryInfo(_updateFilesDir + "\\Patch"); using (var wc = new WebClient()) { wc.DownloadProgressChanged += Wc_DownloadProgressChanged; await wc.DownloadFileTaskAsync(_websiteUrl + $"/{patchInfo.Version}.zip", patchZipFile.FullName); } CurrentState = UpdateState.ApplyingPatch; ZipFile.ExtractToDirectory(patchZipFile.FullName, extractedDir.FullName); var patch = JsonConvert.DeserializeObject <PatchModel>(File.ReadAllText(extractedDir.FullName + "\\Info.json")); var totalBytes = patch.NewFiles.Sum(q => q.Size) + patch.UpdatedFiles.Sum(q => q.Size); long loadedBytes = 0; OnUpdateProgress(new UpdateProgressModel { State = CurrentState, TotalBytes = totalBytes, CompletedBytes = loadedBytes }); var patchContentDir = new DirectoryInfo(extractedDir.FullName + "\\Data"); using (var log = new UpdaterLog(LogPath, true)) { if (patch.UpdatedFiles != null) { foreach (var updatedFileName in patch.UpdatedFiles) { var fi = new FileInfo(_workingDir.FullName + updatedFileName.RelativePath); if (fi.Directory.Exists == false) { fi.Directory.Create(); } string realFileName; bool isPatch = false; if (fi.FullName.EndsWith(".patch", StringComparison.InvariantCultureIgnoreCase)) { realFileName = fi.FullName.Substring(0, fi.FullName.Length - 6); isPatch = true; } else { realFileName = fi.FullName; } File.Delete(realFileName + ".bak"); File.Move(realFileName, realFileName + ".bak"); log.WriteUpdate(realFileName, realFileName + ".bak"); if (isPatch) { using (var input = File.OpenRead(realFileName + ".bak")) using (var output = File.OpenWrite(realFileName)) { BinaryPatchUtility.Apply(input, () => File.Open(patchContentDir.FullName + updatedFileName.RelativePath, FileMode.Open, FileAccess.Read, FileShare.Read), output); } File.Delete(patchContentDir.FullName + updatedFileName.RelativePath); } loadedBytes += updatedFileName.Size; OnUpdateProgress(new UpdateProgressModel { State = CurrentState, TotalBytes = totalBytes, CompletedBytes = loadedBytes }); Thread.Sleep(1); } } if (patch.NewFiles != null) { foreach (var newFileName in patch.NewFiles) { var fi = new FileInfo(_workingDir.FullName + newFileName.RelativePath); if (fi.Directory.Exists == false) { fi.Directory.Create(); } log.WriteAdd(fi.FullName); if (fi.Exists) { fi.Delete(); } File.Move(patchContentDir.FullName + newFileName.RelativePath, fi.FullName); loadedBytes += newFileName.Size; OnUpdateProgress(new UpdateProgressModel { State = CurrentState, TotalBytes = totalBytes, CompletedBytes = loadedBytes }); Thread.Sleep(1); } } if (patch.DeletedFiles != null) { foreach (var patchDeletedFile in patch.DeletedFiles) { var fi = new FileInfo(_workingDir + patchDeletedFile); File.Delete(fi.FullName + ".bak"); File.Move(fi.FullName, fi.FullName + ".bak"); log.WriteDelete(fi.FullName, fi.FullName + ".bak"); } } log.Complete(); } _updaterConfig.VersionProvider.SaveVersion(patch.Version); CurrentState = UpdateState.Idle; _updateFilesDir.Delete(true); OnPatchingCompleted(patch); } catch (Exception e) { CurrentState = UpdateState.Idle; OnPatchingError(e); Rollback(); } }