public async Task<string> ApplyReleases(UpdateInfo updateInfo, Action<int> progress = null) { var applyReleases = new ApplyReleasesImpl(applicationName, rootAppDirectory); await acquireUpdateLock(); return await applyReleases.ApplyReleases(updateInfo, false, false, progress); }
public async Task<string> ApplyReleases(UpdateInfo updateInfo, bool silentInstall, Action<int> progress = null) { progress = progress ?? (_ => { }); var release = await createFullPackagesFromDeltas(updateInfo.ReleasesToApply, updateInfo.CurrentlyInstalledVersion); progress(10); if (release == null) { this.Log().Info("No release to install, running the app"); await invokePostInstall(updateInfo.CurrentlyInstalledVersion.Version, true, true); return getDirectoryForRelease(updateInfo.CurrentlyInstalledVersion.Version).FullName; } var ret = await this.ErrorIfThrows(() => installPackageToAppDir(updateInfo, release), "Failed to install package to app dir"); progress(30); var currentReleases = await this.ErrorIfThrows(() => updateLocalReleasesFile(), "Failed to update local releases file"); progress(50); var newVersion = currentReleases.MaxBy(x => x.Version).First().Version; await this.ErrorIfThrows(() => invokePostInstall(newVersion, currentReleases.Count == 1 && !silentInstall, false), "Failed to invoke post-install"); progress(75); try { await cleanDeadVersions(newVersion); } catch (Exception ex) { this.Log().WarnException("Failed to clean dead versions, continuing anyways", ex); } progress(100); return ret; }
public async Task<string> ApplyReleases(UpdateInfo updateInfo, bool silentInstall, bool attemptingFullInstall, Action<int> progress = null) { progress = progress ?? (_ => { }); var release = await createFullPackagesFromDeltas(updateInfo.ReleasesToApply, updateInfo.CurrentlyInstalledVersion); progress(10); if (release == null) { if (attemptingFullInstall) { this.Log().Info("No release to install, running the app"); await invokePostInstall(updateInfo.CurrentlyInstalledVersion.Version, false, true, silentInstall); } progress(100); return getDirectoryForRelease(updateInfo.CurrentlyInstalledVersion.Version).FullName; } var ret = await this.ErrorIfThrows(() => installPackageToAppDir(updateInfo, release), "Failed to install package to app dir"); progress(30); var currentReleases = await this.ErrorIfThrows(() => updateLocalReleasesFile(), "Failed to update local releases file"); progress(50); var newVersion = currentReleases.MaxBy(x => x.Version).First().Version; executeSelfUpdate(newVersion); await this.ErrorIfThrows(() => invokePostInstall(newVersion, attemptingFullInstall, false, silentInstall), "Failed to invoke post-install"); progress(75); this.Log().Info("Starting fixPinnedExecutables"); this.ErrorIfThrows(() => fixPinnedExecutables(updateInfo.FutureReleaseEntry.Version)); this.Log().Info("Fixing up tray icons"); var trayFixer = new TrayStateChanger(); var appDir = new DirectoryInfo(Utility.AppDirForRelease(rootAppDirectory, updateInfo.FutureReleaseEntry)); var allExes = appDir.GetFiles("*.exe").Select(x => x.Name).ToList(); this.ErrorIfThrows(() => trayFixer.RemoveDeadEntries(allExes, rootAppDirectory, updateInfo.FutureReleaseEntry.Version.ToString())); progress(80); unshimOurselves(); progress(85); try { var currentVersion = updateInfo.CurrentlyInstalledVersion != null ? updateInfo.CurrentlyInstalledVersion.Version : null; await cleanDeadVersions(currentVersion, newVersion); } catch (Exception ex) { this.Log().WarnException("Failed to clean dead versions, continuing anyways", ex); } progress(100); return ret; }
public AppUpdate(UpdateInfo _updateInfo, string Changes) { InitializeComponent(); UpdateInformation = _updateInfo; CurrentVersion = UpdateInformation.CurrentlyInstalledVersion.Version.ToString(); NewVersion = UpdateInformation.FutureReleaseEntry.Version.ToString(); ChangeLogSource = Changes; this.DataContext = this; Loaded += AppUpdate_Loaded; }
public async Task<string> ApplyReleases(UpdateInfo updateInfo, bool silentInstall, bool attemptingFullInstall, Action<int> progress = null) { progress = progress ?? (_ => { }); var release = await createFullPackagesFromDeltas(updateInfo.ReleasesToApply, updateInfo.CurrentlyInstalledVersion); progress(10); if (release == null) { if (attemptingFullInstall) { this.Log().Info("No release to install, running the app"); await invokePostInstall(updateInfo.CurrentlyInstalledVersion.Version, false, true, silentInstall); } progress(100); return getDirectoryForRelease(updateInfo.CurrentlyInstalledVersion.Version).FullName; } var target = getDirectoryForRelease(release.Version); var ret = await this.ErrorIfThrows(() => installPackageToAppDir(updateInfo, release, (p) => progress(10 + (int)((double)p * 45.0 / 100.0))), "Failed to install package to app dir"); var currentReleases = await this.ErrorIfThrows(() => updateLocalReleasesFile(), "Failed to update local releases file"); progress(60); var newVersion = currentReleases.MaxBy(x => x.Version).First().Version; executeSelfUpdate(newVersion); await this.ErrorIfThrows(() => invokePostInstall(newVersion, attemptingFullInstall, false, silentInstall), "Failed to invoke post-install"); progress(75); this.Log().Info("Starting fixPinnedExecutables"); this.ErrorIfThrows(() => fixPinnedExecutables(updateInfo.FutureReleaseEntry.Version)); progress(80); unshimOurselves(); progress(85); try { var currentVersion = updateInfo.CurrentlyInstalledVersion != null ? updateInfo.CurrentlyInstalledVersion.Version : null; await cleanDeadVersions(currentVersion, newVersion); } catch (Exception ex) { this.Log().WarnException("Failed to clean dead versions, continuing anyways", ex); } progress(100); return ret; }
public AboutApp(UpdateInfo _updateInfo, string Changes) { InitializeComponent(); UpdateInformation = _updateInfo; CurrentVersion = UpdateInformation.CurrentlyInstalledVersion.Version.ToString(); NewVersion = UpdateInformation.FutureReleaseEntry.Version.ToString(); ChangeLogSource = Changes; this.DataContext = this; Loaded += AppUpdate_Loaded; if (NewVersion != CurrentVersion) { UpdateButton.IsEnabled = true; } }
async Task<string> installPackageToAppDir(UpdateInfo updateInfo, ReleaseEntry release) { var pkg = new ZipPackage(Path.Combine(updateInfo.PackageDirectory, release.Filename)); var target = getDirectoryForRelease(release.Version); // NB: This might happen if we got killed partially through applying the release if (target.Exists) { this.Log().Warn("Found partially applied release folder, killing it: " + target.FullName); await Utility.DeleteDirectory(target.FullName); } target.Create(); // Copy all of the files out of the lib/ dirs in the NuGet package // into our target App directory. // // NB: We sort this list in order to guarantee that if a Net20 // and a Net40 version of a DLL get shipped, we always end up // with the 4.0 version. this.Log().Info("Writing files to app directory: {0}", target.FullName); var toWrite = pkg.GetLibFiles().Where(x => pathIsInFrameworkProfile(x, appFrameworkVersion)) .OrderBy(x => x.Path) .ToList(); // NB: Because of the above NB, we cannot use ForEachAsync here, we // have to copy these files in-order. Once we fix assembly resolution, // we can kill both of these NBs. await Task.Run(() => toWrite.ForEach(x => copyFileToLocation(target, x))); await pkg.GetContentFiles().ForEachAsync(x => copyFileToLocation(target, x)); var newCurrentVersion = updateInfo.FutureReleaseEntry.Version; // Perform post-install; clean up the previous version by asking it // which shortcuts to install, and nuking them. Then, run the app's // post install and set up shortcuts. this.ErrorIfThrows(() => runPostInstallAndCleanup(newCurrentVersion, updateInfo.IsBootstrapping)); return target.FullName; }
Task <string> installPackageToAppDir(UpdateInfo updateInfo, ReleaseEntry release, Action <int> progress) { return(Task.Run(async() => { var target = getDirectoryForRelease(release.Version); // NB: This might happen if we got killed partially through applying the release if (target.Exists) { this.Log().Warn("Found partially applied release folder, killing it: " + target.FullName); await Utility.DeleteDirectory(target.FullName); } target.Create(); var totalSize = GetTotalUncompressedSize(updateInfo, release); var currentExtractedSize = 0L; using (var stream = File.OpenRead(Path.Combine(updateInfo.PackageDirectory, release.Filename))) { // progress.Report(new InstallerStep("Extracting")); var zipIn = new ZipInputStream(stream); var zipEntry = zipIn.GetNextEntry(); while (zipEntry != null) { var entryName = zipEntry.Name; var pathParts = entryName.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); var foundLib = false; foreach (var part in pathParts) { if (part.Equals("lib", StringComparison.InvariantCulture)) { foundLib = true; } } if (!foundLib) { zipEntry = zipIn.GetNextEntry(); continue; } var buffer = new byte[4096]; var fullZipToPath = Path.Combine(target.FullName, entryName.Replace('/', Path.DirectorySeparatorChar)); var directoryName = zipEntry.IsFile ? Path.GetDirectoryName(fullZipToPath) : fullZipToPath; if (!string.IsNullOrEmpty(directoryName)) { Directory.CreateDirectory(directoryName); } using (var streamWriter = File.Create(fullZipToPath)) { currentExtractedSize += zipEntry.Size; StreamUtils.Copy(zipIn, streamWriter, buffer); progress((int)((double)currentExtractedSize * 100.0 / (double)totalSize)); } zipEntry = zipIn.GetNextEntry(); } } this.Log().Info("Writing files to app directory: {0}", target.FullName); // Move all of the files out of the lib/ dirs in the NuGet package // into our target App directory. // // NB: We sort this list in order to guarantee that if a Net20 // and a Net40 version of a DLL get shipped, we always end up // with the 4.0 version. var libDir = target.GetDirectories().First(x => x.Name.Equals("lib", StringComparison.OrdinalIgnoreCase)); var toMove = libDir.GetDirectories().OrderBy(x => x.Name); toMove.ForEach(ld => { ld.GetDirectories() .ForEachAsync(subdir => subdir.MoveTo(subdir.FullName.Replace(ld.FullName, target.FullName))) .Wait(); ld.GetFiles() .ForEachAsync(file => { var tgt = Path.Combine(target.FullName, file.Name); this.Log().Info("Moving file {0} to {1}", file.FullName, tgt); if (File.Exists(tgt)) { Utility.DeleteFileHarder(tgt, true); } file.MoveTo(tgt); }) .Wait(); }); await Utility.DeleteDirectory(libDir.FullName); return target.FullName; })); }
Task<string> installPackageToAppDir(UpdateInfo updateInfo, ReleaseEntry release) { return Task.Run(async () => { var zipper = new FastZip(); var target = getDirectoryForRelease(release.Version); // NB: This might happen if we got killed partially through applying the release if (target.Exists) { this.Log().Warn("Found partially applied release folder, killing it: " + target.FullName); await Utility.DeleteDirectory(target.FullName); } target.Create(); this.Log().Info("Writing files to app directory: {0}", target.FullName); zipper.ExtractZip( Path.Combine(updateInfo.PackageDirectory, release.Filename), target.FullName, FastZip.Overwrite.Always, (o) => true, null, @"lib", true); // Move all of the files out of the lib/ dirs in the NuGet package // into our target App directory. // // NB: We sort this list in order to guarantee that if a Net20 // and a Net40 version of a DLL get shipped, we always end up // with the 4.0 version. var libDir = target.GetDirectories().First(x => x.Name.Equals("lib", StringComparison.OrdinalIgnoreCase)); var toMove = libDir.GetDirectories().OrderBy(x => x.Name); toMove.ForEach(ld => { ld.GetDirectories() .ForEachAsync(subdir => subdir.MoveTo(subdir.FullName.Replace(ld.FullName, target.FullName))) .Wait(); ld.GetFiles() .ForEachAsync(file => { var tgt = Path.Combine(target.FullName, file.Name); this.Log().Info("Moving file {0} to {1}", file.FullName, tgt); file.MoveTo(tgt); }) .Wait(); }); await Utility.DeleteDirectory(libDir.FullName); return target.FullName; }); }
static long GetTotalUncompressedSize(UpdateInfo updateInfo, ReleaseEntry release) { long totalSize = 0; using (var stream = File.OpenRead(Path.Combine(updateInfo.PackageDirectory, release.Filename))) { var zipIn = new ZipInputStream(stream); var zipEntry = zipIn.GetNextEntry(); while (zipEntry != null) { var pathParts = zipEntry.Name.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); var foundLib = false; foreach (var part in pathParts) { if (part.Equals("lib", StringComparison.InvariantCulture)) { foundLib = true; } } if (!foundLib) { zipEntry = zipIn.GetNextEntry(); continue; } totalSize += zipEntry.Size; zipEntry = zipIn.GetNextEntry(); } } return totalSize; }
Task<string> installPackageToAppDir(UpdateInfo updateInfo, ReleaseEntry release, Action<int> progress) { return Task.Run(async () => { var target = getDirectoryForRelease(release.Version); // NB: This might happen if we got killed partially through applying the release if (target.Exists) { this.Log().Warn("Found partially applied release folder, killing it: " + target.FullName); await Utility.DeleteDirectory(target.FullName); } target.Create(); var totalSize = GetTotalUncompressedSize(updateInfo, release); var currentExtractedSize = 0L; using (var stream = File.OpenRead(Path.Combine(updateInfo.PackageDirectory, release.Filename))) { // progress.Report(new InstallerStep("Extracting")); var zipIn = new ZipInputStream(stream); var zipEntry = zipIn.GetNextEntry(); while (zipEntry != null) { var entryName = zipEntry.Name; var pathParts = entryName.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); var foundLib = false; foreach (var part in pathParts) { if (part.Equals("lib", StringComparison.InvariantCulture)) { foundLib = true; } } if (!foundLib) { zipEntry = zipIn.GetNextEntry(); continue; } var buffer = new byte[4096]; var fullZipToPath = Path.Combine(target.FullName, entryName.Replace('/', Path.DirectorySeparatorChar)); var directoryName = zipEntry.IsFile ? Path.GetDirectoryName(fullZipToPath) : fullZipToPath; if (!string.IsNullOrEmpty(directoryName)) Directory.CreateDirectory(directoryName); using (var streamWriter = File.Create(fullZipToPath)) { currentExtractedSize += zipEntry.Size; StreamUtils.Copy(zipIn, streamWriter, buffer); progress((int)((double) currentExtractedSize * 100.0 / (double) totalSize)); } zipEntry = zipIn.GetNextEntry(); } } this.Log().Info("Writing files to app directory: {0}", target.FullName); // Move all of the files out of the lib/ dirs in the NuGet package // into our target App directory. // // NB: We sort this list in order to guarantee that if a Net20 // and a Net40 version of a DLL get shipped, we always end up // with the 4.0 version. var libDir = target.GetDirectories().First(x => x.Name.Equals("lib", StringComparison.OrdinalIgnoreCase)); var toMove = libDir.GetDirectories().OrderBy(x => x.Name); toMove.ForEach(ld => { ld.GetDirectories() .ForEachAsync(subdir => subdir.MoveTo(subdir.FullName.Replace(ld.FullName, target.FullName))) .Wait(); ld.GetFiles() .ForEachAsync(file => { var tgt = Path.Combine(target.FullName, file.Name); this.Log().Info("Moving file {0} to {1}", file.FullName, tgt); if (File.Exists(tgt)) Utility.DeleteFileHarder(tgt, true); file.MoveTo(tgt); }) .Wait(); }); await Utility.DeleteDirectory(libDir.FullName); return target.FullName; }); }
async Task<string> installPackageToAppDir(UpdateInfo updateInfo, ReleaseEntry release) { string tmpDir = default(string); bool shouldDeleteTmpDir = findShortTemporaryDir(out tmpDir); var fs = new PhysicalFileSystem(tmpDir); var pkg = new OptimizedZipPackage(fs, Path.Combine(updateInfo.PackageDirectory, release.Filename)); var target = getDirectoryForRelease(release.Version); // NB: This might happen if we got killed partially through applying the release if (target.Exists) { this.Log().Warn("Found partially applied release folder, killing it: " + target.FullName); await Utility.DeleteDirectory(target.FullName); } target.Create(); // Copy all of the files out of the lib/ dirs in the NuGet package // into our target App directory. // // NB: We sort this list in order to guarantee that if a Net20 // and a Net40 version of a DLL get shipped, we always end up // with the 4.0 version. this.Log().Info("Writing files to app directory: {0}", target.FullName); var toWrite = pkg.GetLibFiles().Where(x => pathIsInFrameworkProfile(x, appFrameworkVersion)) .OrderBy(x => x.Path) .ToList(); // NB: Because of the above NB, we cannot use ForEachAsync here, we // have to copy these files in-order. Once we fix assembly resolution, // we can kill both of these NBs. await Task.Run(() => toWrite.ForEach(x => copyFileToLocation(target, x))); await pkg.GetContentFiles().ForEachAsync(x => copyFileToLocation(target, x)); if (shouldDeleteTmpDir) { await Utility.DeleteDirectory(tmpDir); } return target.FullName; }
static bool NotEqualVersions(UpdateInfo updateInfo) => updateInfo.FutureReleaseEntry != updateInfo.CurrentlyInstalledVersion;
public static bool NeedsUpdate(this UpdateInfo updates) { return(updates.ReleasesToApply.Count > 0); }
public async Task <string> ApplyReleases(UpdateInfo updateInfo, bool silentInstall, bool attemptingFullInstall, Action <int> progress = null) { progress = progress ?? (_ => { }); progress(0); var release = await createFullPackagesFromDeltas(updateInfo.ReleasesToApply, updateInfo.CurrentlyInstalledVersion); progress(10); if (release == null) { if (attemptingFullInstall) { this.Log().Info("No release to install, running the app"); await invokePostInstall(updateInfo.CurrentlyInstalledVersion.Version, false, true, silentInstall); } progress(100); return(getDirectoryForRelease(updateInfo.CurrentlyInstalledVersion.Version).FullName); } var ret = await this.ErrorIfThrows(() => installPackageToAppDir(updateInfo, release), "Failed to install package to app dir"); progress(30); var currentReleases = await this.ErrorIfThrows(() => updateLocalReleasesFile(), "Failed to update local releases file"); progress(50); var newVersion = currentReleases.MaxBy(x => x.Version).First().Version; executeSelfUpdate(newVersion); await this.ErrorIfThrows(() => invokePostInstall(newVersion, attemptingFullInstall, false, silentInstall), "Failed to invoke post-install"); progress(75); this.Log().Info("Starting fixPinnedExecutables"); this.ErrorIfThrows(() => fixPinnedExecutables(updateInfo.FutureReleaseEntry.Version)); this.Log().Info("Fixing up tray icons"); var trayFixer = new TrayStateChanger(); var appDir = new DirectoryInfo(Utility.AppDirForRelease(rootAppDirectory, updateInfo.FutureReleaseEntry)); var allExes = appDir.GetFiles("*.exe").Select(x => x.Name).ToList(); this.ErrorIfThrows(() => trayFixer.RemoveDeadEntries(allExes, rootAppDirectory, updateInfo.FutureReleaseEntry.Version.ToString())); progress(80); unshimOurselves(); progress(85); try { var currentVersion = updateInfo.CurrentlyInstalledVersion != null ? updateInfo.CurrentlyInstalledVersion.Version : null; await cleanDeadVersions(currentVersion, newVersion); } catch (Exception ex) { this.Log().WarnException("Failed to clean dead versions, continuing anyways", ex); } progress(100); return(ret); }
private void CheckForUpdateCallback(Action<string> callback, UpdateInfo updateInfo) { if (updateInfo == null) { callback(null); } else if (!updateInfo.ReleasesToApply.Any()) { callback(null); } else { _updateInfo = updateInfo; var latest = _updateInfo.ReleasesToApply.OrderBy(x => x.Version).Last(); callback(latest.Version.ToString()); } }
public async Task <string> ApplyReleases(UpdateInfo updateInfo, bool silentInstall, bool attemptingFullInstall, Action <int> progress = null) { progress = progress ?? (_ => { }); var release = await createFullPackagesFromDeltas(updateInfo.ReleasesToApply, updateInfo.CurrentlyInstalledVersion, x => progress(x * 4 / 5)); // The numbers in these progress reports are rather arbitrary. Experience indicates that applying the deltas takes most of the time. // Allocating 80% to that process is a crude approximation. The remaining identifiable steps are simply allocated equal time chunks // of 4% each. // These changes should probably not be pushed upstream without further enhancement. The time to apply deltas is probably dependent // on the size and complexity of the package being updated. progress(80); if (release == null) { if (attemptingFullInstall) { this.Log().Info("No release to install, running the app"); // JohnT: this doesn't work, because if the second argument ('isInitialInstall') is false, invokePostInstall does NOT // run the app. And we mustn't make it do so, or it will try to run the app after installing updates, // since passing attemptingFullInstall for this argument in the other call below is what prevents running // the app post-install when it is already running and updating itself. // We could pass true here for isInitialInstall, but then the app will be invoked as if for the first time, // but it clearly isn't the first time, because it was already installed. // For our fork, it doesn't currently matter, because if we ARE running the full installer and there is // nothing to do, we redo everything, which means that at this point in the code there IS something // to install, namely, the current full release. So I'm just not trying to fix it for now. // If we need to make this run the app we probably need distinct arguments for isInitialInstall and // attemptingFullInstall (or 'runFullApp' or similar). await invokePostInstall(updateInfo.CurrentlyInstalledVersion.Version, false, true, silentInstall); } progress(100); return(getDirectoryForRelease(updateInfo.CurrentlyInstalledVersion.Version).FullName); } var ret = await this.ErrorIfThrows(() => installPackageToAppDir(updateInfo, release), "Failed to install package to app dir"); progress(84); var currentReleases = await this.ErrorIfThrows(() => updateLocalReleasesFile(), "Failed to update local releases file"); progress(88); var newVersion = currentReleases.MaxBy(x => x.Version).First().Version; executeSelfUpdate(newVersion); await this.ErrorIfThrows(() => invokePostInstall(newVersion, attemptingFullInstall, false, silentInstall), "Failed to invoke post-install"); progress(92); this.Log().Info("Starting fixPinnedExecutables"); this.ErrorIfThrows(() => fixPinnedExecutables(updateInfo.FutureReleaseEntry.Version)); this.Log().Info("Fixing up tray icons"); var trayFixer = new TrayStateChanger(); var appDir = new DirectoryInfo(Utility.AppDirForRelease(rootAppDirectory, updateInfo.FutureReleaseEntry)); var allExes = appDir.GetFiles("*.exe").Select(x => x.Name).ToList(); this.ErrorIfThrows(() => trayFixer.RemoveDeadEntries(allExes, rootAppDirectory, updateInfo.FutureReleaseEntry.Version.ToString())); progress(96); unshimOurselves(); progress(98); try { var currentVersion = updateInfo.CurrentlyInstalledVersion != null ? updateInfo.CurrentlyInstalledVersion.Version : null; await cleanDeadVersions(currentVersion, newVersion); } catch (Exception ex) { this.Log().WarnException("Failed to clean dead versions, continuing anyways", ex); } progress(100); return(ret); }
Task<string> installPackageToAppDir(UpdateInfo updateInfo, ReleaseEntry release) { return Task.Run(async () => { var target = getDirectoryForRelease(release.Version); // NB: This might happen if we got killed partially through applying the release if (target.Exists) { this.Log().Warn("Found partially applied release folder, killing it: " + target.FullName); await Utility.DeleteDirectory(target.FullName); } target.Create(); this.Log().Info("Writing files to app directory: {0}", target.FullName); await ReleasePackage.ExtractZipForInstall( Path.Combine(updateInfo.PackageDirectory, release.Filename), target.FullName); return target.FullName; }); }
/// <summary> /// Apply releases found and downloaded by a previous update check using Squirrel UpdateManager and return true when finished. /// </summary> /// <returns></returns> public static async Task<string> ApplyReleasesAsync(UpdateInfo updateInfo) { var appName = GetAppName(); var updateLocation = GetUpdateLocation(); var ret = String.Empty; _log.Debug("Apply Releases. Called " + Utilities.GetCallerName() + " with UpdateLocation = \"" + updateLocation + "\" and AppName = " + appName + "\"."); using (var mgr = new Squirrel.UpdateManager(updateLocation, appName, Squirrel.FrameworkVersion.Net45)) { try { var s = await mgr.ApplyReleases(updateInfo).ConfigureAwait(false); ret = s; } catch (Exception e) { _log.Error(Utilities.GetCallerName() + " error while applying releases with UpdateLocation = \"" + updateLocation + "\" and AppName = " + appName + ", thrown " + e.GetType().ToString() + " with message \"" + e.Message + "\".", e); throw; } } return ret; }
static bool HasFutureReleaseEntry(UpdateInfo updateInfo) => updateInfo.FutureReleaseEntry != null;
void RefreshInfo(UpdateInfo updateInfo) { NewVersionAvailable = HasFutureReleaseEntry(updateInfo) && NotEqualVersions(updateInfo); UpdateStatus = updateInfo.CurrentlyInstalledVersion.Version + " installed"; if (NewVersionAvailable) { UpdateStatus += ", " + updateInfo.FutureReleaseEntry.Version + " available" + (updateInfo.FutureReleaseEntry.IsDelta ? " (delta)" : ""); } else UpdateStatus += " (latest)"; }