public IEnumerable <StatusReportItem> Verify(IPatchDestination destination, HashSet <string> patchExclusions) { if (!destination.TryLock()) { yield return(new StatusReportItem { Status = $"cannot acquire lock on {destination.LongDescription} to verify 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)) { yield return(new StatusReportItem { Status = $"{destination.LongDescription} will not patch {patch.TargetPath} because it was excluded from patching by the user" }); continue; } if (!destination.TryGetSource(patch.TargetPath, out string source)) { ConfigManager.LogManager.LogDebug( $"{patch.TargetPath} does not exist in {destination.LongDescription}; patch does not apply"); continue; } if (patch.IsApplied(source)) { yield return(new StatusReportItem { Status = $"{destination.LongDescription} has already patched {patch.TargetPath}", // there will be a lot of these, don't show them in small views Flags = StatusReportItem.StatusFlags.Verbose | StatusReportItem.StatusFlags.ConfigurationUpToDate }); } else { yield return(new StatusReportItem { Status = $"{destination.LongDescription} is missing some patches in {patch.TargetPath}", Recommendation = "Apply patches", Link = StatusReportItem.ProfileEditor, Severity = StatusReportItem.SeverityCode.Error }); } } if (!destination.TryUnlock()) { ConfigManager.LogManager.LogError( $"cannot release lock on {destination.LongDescription} after verifying patches"); } }
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 }); } }