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 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); }
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); }