public PatchApplication(IPatchDestinationWritable destination, bool enabled, bool useRemote, string patchSet, params string[] patchesRoots) { PatchSet = patchSet; PatchesRoots = patchesRoots; Destination = destination; Enabled = enabled; UseRemote = useRemote; PatchList patches = new PatchList(); string selectedVersion = null; foreach (string patchesRoot in PatchesRoots) { string previouslySelectedVersion = selectedVersion; PatchList loaded = Destination.SelectPatches(patchesRoot, ref selectedVersion, PatchSet); if (previouslySelectedVersion != null && selectedVersion != null && string.Compare(selectedVersion, previouslySelectedVersion, StringComparison.InvariantCulture) > 0) { // replaced with higher version patches = new PatchList(); } patches.Merge(loaded); } Patches = patches; SelectedVersion = selectedVersion; Status = StatusCodes.Unknown; }
private static bool WriteBack(IPatchDestinationWritable destination, PatchFile patch, string patched, string verbing, out StatusReportItem status) { if (destination.TryWritePatched(patch.TargetPath, patched)) { status = new StatusReportItem { Status = $"{destination.LongDescription} successfully wrote {patch.TargetPath} after {verbing} patch" }; return(true); } status = new StatusReportItem { Status = $"{destination.LongDescription} could not write {patch.TargetPath} after {verbing} patch", Severity = StatusReportItem.SeverityCode.Error, Recommendation = "please ensure you have write permission to all the files in the target location" }; return(false); }
public IEnumerable <StatusReportItem> Apply(IPatchDestinationWritable destination, HashSet <string> patchExclusions) => DoApply(destination, destination, patchExclusions, Mode.Apply);
public IEnumerable <StatusReportItem> Revert(IPatchDestinationWritable destination, HashSet <string> patchExclusions) { if (!destination.TryLock()) { yield return(new StatusReportItem { Status = $"cannot acquire lock on {destination.LongDescription} to revert patches", Recommendation = "close any programs that are holding a lock on this location", Severity = StatusReportItem.SeverityCode.Error }); yield break; } foreach (PatchFile patch in _patches) { if (patchExclusions.Contains(patch.TargetPath)) { continue; } if (!destination.TryGetSource(patch.TargetPath, out string source)) { yield return(new StatusReportItem { Status = $"{patch.TargetPath} does not exist in {destination.LongDescription}; ignoring patch" }); continue; } if (!patch.IsApplied(source)) { // patch not present in this file any more, go to next patch yield return(new StatusReportItem { Status = $"{destination.LongDescription} does not have our patches for {patch.TargetPath}" }); continue; } if (destination.TryRestoreOriginal(patch.TargetPath)) { // restored original file for this version, no need to revert patch yield return(new StatusReportItem { Status = $"{destination.LongDescription} restored original file {patch.TargetPath}", Flags = StatusReportItem.StatusFlags.ConfigurationUpToDate }); continue; } if (!patch.TryRevert(source, out string patched, out string failureStatus)) { // could not apply reverse patch; keep going trying to fix up as much as possible yield return(new StatusReportItem { Status = $"{destination.LongDescription} {failureStatus}", Recommendation = "please repair DCS installation using dcs_updater.exe", Severity = StatusReportItem.SeverityCode.Error }); } if (!WriteBack(destination, patch, patched, "reverting", out StatusReportItem status)) { yield return(status); destination.TryUnlock(); yield break; } yield return(status); } if (!destination.TryUnlock()) { yield return(new StatusReportItem { Status = $"cannot release lock on {destination.LongDescription} after reverting patches", Recommendation = "please restart and try the revert patches process again", Severity = StatusReportItem.SeverityCode.Error }); } }
private IEnumerable <StatusReportItem> DoApply(IPatchDestination destination, IPatchDestinationWritable writable, HashSet <string> patchExclusions, Mode mode) { // set up according to mode string verb; string verbing; switch (mode) { case Mode.Simulate: verb = "simulate"; verbing = "simulating"; break; case Mode.Apply: verb = "apply"; verbing = "applying"; break; default: throw new ArgumentOutOfRangeException(nameof(mode), mode, null); } if (!destination.TryLock()) { yield return(new StatusReportItem { Status = $"cannot acquire lock on {destination.LongDescription} to {verb} patches", Recommendation = "close any programs that are holding a lock on this location", Severity = StatusReportItem.SeverityCode.Error }); yield break; } foreach (PatchFile patch in _patches) { if (patchExclusions.Contains(patch.TargetPath)) { continue; } if (!destination.TryGetSource(patch.TargetPath, out string source)) { yield return(new StatusReportItem { Status = $"{patch.TargetPath} does not exist in {destination.LongDescription}; ignoring patch" }); continue; } if (patch.IsApplied(source)) { // already applied, go to next patch yield return(new StatusReportItem { Status = $"{destination.LongDescription} has already patched {patch.TargetPath}" }); continue; } if (!patch.TryApply(source, out string patched, out string failureStatus, out string expectedCode)) { // send a general failure message that will become the header of the dialog box if any string failedPatchRecommendation = "Please make sure you do not have viewport mods installed. If your DCS installation is free from modifications and patches still fail, then install a newer Helios distribution or patches with support for this DCS version."; yield return(new StatusReportItem { Status = $"{destination.LongDescription} could not install patches. You may have viewport mods installed that need to be removed or DCS may have changed too much during a recent update.", Recommendation = failedPatchRecommendation, Severity = StatusReportItem.SeverityCode.Error }); // send detail including code yield return(new StatusReportItem { Status = $"{destination.LongDescription} {failureStatus}", Recommendation = failedPatchRecommendation, Severity = StatusReportItem.SeverityCode.Error, Code = expectedCode }); // could not patch; fatal destination.TryUnlock(); yield break; } if (mode == Mode.Simulate) { continue; } if (!writable.TrySaveOriginal(patch.TargetPath)) { // abort yield return(new StatusReportItem { Status = $"{destination.LongDescription} could not save original copy of {patch.TargetPath}", Recommendation = "please check write permissions to make sure you can write files in the DCS installation location", Severity = StatusReportItem.SeverityCode.Error }); destination.TryUnlock(); yield break; } if (!WriteBack(writable, patch, patched, verbing, out StatusReportItem status)) { // abort yield return(status); destination.TryUnlock(); yield break; } // success result yield return(status); } if (!destination.TryUnlock()) { yield return(new StatusReportItem { Status = $"cannot release lock on {destination.LongDescription} after {verbing} patches", Recommendation = $"please restart and try the {verb} process again", Severity = StatusReportItem.SeverityCode.Error }); } }