// For self-patching applications only - should be called after Run(true) returns PatchResult.Success // Starts specified self patcher executable with required parameters public bool ApplySelfPatch(string selfPatcherExecutable, string postSelfPatchExecutable = null) { IsRunning = true; Operation = PatchOperation.ApplyingSelfPatch; comms.InitializeFileLogger(); comms.ListenerCallStarted(); try { selfPatcherExecutable = selfPatcherExecutable.Trim(); if (postSelfPatchExecutable != null) { postSelfPatchExecutable = postSelfPatchExecutable.Trim(); } if (!File.Exists(selfPatcherExecutable)) { Result = PatchResult.Failed; FailReason = PatchFailReason.SelfPatcherNotFound; FailDetails = Localization.Get(StringId.E_SelfPatcherDoesNotExist); comms.Log(comms.FailDetails); return(false); } string instructionsPath = comms.CachePath + PatchParameters.SELF_PATCH_INSTRUCTIONS_FILENAME; string completedInstructionsPath = comms.CachePath + PatchParameters.SELF_PATCH_COMPLETED_INSTRUCTIONS_FILENAME; if (!File.Exists(instructionsPath)) { Result = PatchResult.Failed; FailReason = PatchFailReason.Unknown; FailDetails = ""; comms.LogToFile(Localization.Get(StringId.E_XDoesNotExist, instructionsPath)); return(false); } FileInfo selfPatcher = new FileInfo(selfPatcherExecutable); string args = "\"" + instructionsPath + "\" \"" + completedInstructionsPath + "\""; if (!string.IsNullOrEmpty(postSelfPatchExecutable) && File.Exists(postSelfPatchExecutable)) { args += " \"" + postSelfPatchExecutable + "\""; } ProcessStartInfo startInfo = new ProcessStartInfo(selfPatcher.FullName) { Arguments = args, WorkingDirectory = selfPatcher.DirectoryName }; Process.Start(startInfo); Result = PatchResult.Success; } catch (Exception e) { Result = PatchResult.Failed; FailReason = PatchFailReason.FatalException; FailDetails = e.ToString(); comms.LogToFile(e); return(false); } finally { comms.DisposeFileLogger(); IsRunning = false; comms.ListenerCallFinished(); } Process.GetCurrentProcess().Kill(); return(true); }
public PatchResult Run() { if (comms.Cancel) { return(PatchResult.Failed); } if (comms.IsUnderMaintenance()) { return(PatchResult.Failed); } Stopwatch timer = Stopwatch.StartNew(); comms.Stage = PatchStage.CalculatingFilesToUpdate; comms.Log(Localization.Get(StringId.CalculatingNewOrChangedFiles)); List <VersionItem> filesToUpdate = FindFilesToUpdate(); if (filesToUpdate.Count == 0) { return(PatchResult.AlreadyUpToDate); } if (comms.Cancel) { return(PatchResult.Failed); } comms.Log(Localization.Get(StringId.CalculatingFilesToDownload)); List <VersionItem> filesToDownload = FindFilesToDownload(filesToUpdate); if (comms.Cancel) { return(PatchResult.Failed); } if (filesToDownload.Count > 0 && comms.VerifyFiles) { comms.Stage = PatchStage.VerifyingFilesOnServer; for (int i = 0; i < filesToDownload.Count; i++) { if (comms.Cancel) { return(PatchResult.Failed); } VersionItem item = filesToDownload[i]; long fileSize; if (!comms.DownloadManager.FileExistsAtUrl(comms.VersionInfo.GetDownloadURLFor(item), out fileSize)) { comms.FailReason = PatchFailReason.FileDoesNotExistOnServer; comms.FailDetails = Localization.Get(StringId.E_FileXDoesNotExistOnServer, item.Path); return(PatchResult.Failed); } else if (fileSize > 0L && fileSize != item.CompressedFileSize) { comms.FailReason = PatchFailReason.FileIsNotValidOnServer; comms.FailDetails = Localization.Get(StringId.E_FileXIsNotValidOnServer, item.Path); return(PatchResult.Failed); } } } if (filesToDownload.Count > 0) { comms.Log(Localization.Get(StringId.DownloadingXFiles, filesToDownload.Count)); } if (filesToUpdate.Count > 0) { comms.Log(Localization.Get(StringId.UpdatingXFiles, filesToUpdate.Count)); } Stopwatch downloadTimer = Stopwatch.StartNew(); if (!DownloadAndUpdateFiles(filesToDownload, filesToUpdate)) { return(PatchResult.Failed); } comms.Log(Localization.Get(StringId.AllFilesAreDownloadedInXSeconds, downloadTimer.ElapsedSeconds())); PatchUtils.DeleteDirectory(comms.DownloadsPath); comms.Log(Localization.Get(StringId.PatchAppliedInXSeconds, timer.ElapsedSeconds())); return(PatchResult.Success); }
// For self-patching applications only - should be called after Run(true) returns PatchResult.Success // Starts specified self patcher executable with required parameters public bool ApplySelfPatch(string selfPatcherExecutable, string postSelfPatchExecutable = null) { selfPatcherExecutable = selfPatcherExecutable.Trim(); if (postSelfPatchExecutable != null) { postSelfPatchExecutable = postSelfPatchExecutable.Trim(); } if (!File.Exists(selfPatcherExecutable)) { comms.Log(Localization.Get(StringId.E_SelfPatcherDoesNotExist)); return(false); } string instructionsPath = comms.CachePath + PatchParameters.SELF_PATCH_INSTRUCTIONS_FILENAME; string completedInstructionsPath = comms.CachePath + PatchParameters.SELF_PATCH_COMPLETED_INSTRUCTIONS_FILENAME; if (!File.Exists(instructionsPath)) { return(false); } FileInfo selfPatcher = new FileInfo(selfPatcherExecutable); string args = "\"" + instructionsPath + "\" \"" + completedInstructionsPath + "\""; if (!string.IsNullOrEmpty(postSelfPatchExecutable) && File.Exists(postSelfPatchExecutable)) { args += " \"" + postSelfPatchExecutable + "\""; } ProcessStartInfo startInfo = new ProcessStartInfo(selfPatcher.FullName) { Arguments = args, WorkingDirectory = selfPatcher.DirectoryName }; Process.Start(startInfo); Process.GetCurrentProcess().Kill(); return(true); }
public PatchResult Run() { if (comms.Cancel) { return(PatchResult.Failed); } if (comms.IsUnderMaintenance()) { return(PatchResult.Failed); } if (patchInfo.Files.Count > 0) { PatchUtils.DeleteDirectory(patchDecompressPath); Directory.CreateDirectory(patchDecompressPath); } if (comms.Cancel) { return(PatchResult.Failed); } Stopwatch timer = Stopwatch.StartNew(); if (patchInfo.Files.Count > 0) { FileInfo patchFile = new FileInfo(patchDownloadPath); if (!patchFile.Exists || !patchFile.MatchesSignature(patchInfo.CompressedFileSize, patchInfo.CompressedMd5Hash)) { comms.Stage = PatchStage.DownloadingFiles; Stopwatch downloadTimer = Stopwatch.StartNew(); comms.Log(Localization.Get(StringId.DownloadingPatchX, patchInfo.PatchVersion())); patchFile = comms.DownloadManager.DownloadFileFromURLToPath(patchInfo.DownloadURL, patchDownloadPath, patchInfo.CompressedFileSize); if (patchFile == null) { comms.FailReason = PatchFailReason.DownloadError; comms.FailDetails = Localization.Get(StringId.E_PatchXCouldNotBeDownloaded, patchInfo.PatchVersion()); return(PatchResult.Failed); } else if (!patchFile.MatchesSignature(patchInfo.CompressedFileSize, patchInfo.CompressedMd5Hash)) { comms.FailReason = PatchFailReason.CorruptDownloadError; comms.FailDetails = Localization.Get(StringId.E_DownloadedFileXIsCorrupt, patchInfo.PatchVersion()); return(PatchResult.Failed); } else { comms.Log(Localization.Get(StringId.XDownloadedInYSeconds, patchInfo.PatchVersion(), downloadTimer.ElapsedSeconds())); } } if (comms.Cancel) { return(PatchResult.Failed); } comms.Stage = PatchStage.ExtractingFilesFromArchive; comms.Log(Localization.Get(StringId.DecompressingPatchX, patchInfo.PatchVersion())); ZipUtils.DecompressFolderLZMA(patchFile.FullName, patchDecompressPath); comms.Stage = PatchStage.UpdatingFiles; comms.Log(Localization.Get(StringId.UpdatingXFiles, patchInfo.Files.Count)); int failedItemCount = 0; for (int i = 0; i < patchInfo.Files.Count; i++) { if (comms.Cancel) { return(PatchResult.Failed); } string fileRelativePath = patchInfo.Files[i].Path; string diffFileAbsolutePath = patchDecompressPath + fileRelativePath; if (!File.Exists(diffFileAbsolutePath)) { comms.Log(Localization.Get(StringId.E_DiffOfXDoesNotExist, Path.GetFileName(fileRelativePath))); failedItemCount++; continue; } string decompressAbsolutePath = comms.DecompressedFilesPath + fileRelativePath; if (comms.SelfPatching && ApplyDiffToFile(decompressAbsolutePath, diffFileAbsolutePath, decompressAbsolutePath, i)) { continue; } string localFileAbsolutePath = comms.RootPath + fileRelativePath; string targetPath = comms.SelfPatching ? decompressAbsolutePath : localFileAbsolutePath; if (!ApplyDiffToFile(localFileAbsolutePath, diffFileAbsolutePath, targetPath, i)) { failedItemCount++; } } comms.Log(Localization.Get(StringId.XFilesUpdatedSuccessfully, patchInfo.Files.Count - failedItemCount, patchInfo.Files.Count)); } if (patchInfo.RenamedFiles.Count > 0) { comms.Log(Localization.Get(StringId.RenamingXFiles, patchInfo.RenamedFiles.Count)); if (!RenameItems(patchInfo.RenamedFiles)) { return(PatchResult.Failed); } } // Updating version code to the latest one will be done by SimplePatchTool, after checking // whether or not all files are correctly updated if (patchInfo.ToVersion < comms.VersionInfo.Version) { comms.UpdateVersion(patchInfo.ToVersion); } if (patchInfo.Files.Count > 0) { PatchUtils.DeleteDirectory(patchDecompressPath); File.Delete(patchDownloadPath); } comms.Log(Localization.Get(StringId.PatchAppliedInXSeconds, timer.ElapsedSeconds())); return(PatchResult.Success); }