Пример #1
0
        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;
            }
Пример #8
0
            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;
            }
Пример #13
0
 static bool NotEqualVersions(UpdateInfo updateInfo)
     => updateInfo.FutureReleaseEntry != updateInfo.CurrentlyInstalledVersion;
Пример #14
0
 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);
            }
Пример #16
0
		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;
                });
            }
Пример #19
0
        /// <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;
        }
Пример #20
0
 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)";
 }