Beispiel #1
0
        /// <summary>
        /// Installes the available updates if there is an update available.
        /// </summary>
        /// <returns>Task.</returns>
        public async Task <SquirrelResult> InstallAvailableUpdatesAsync(SquirrelContext context)
        {
            Argument.IsNotNull(() => context);

            var result = new SquirrelResult
            {
                IsUpdateInstalledOrAvailable = false,
                CurrentVersion = GetCurrentApplicationVersion()
            };

            var channelUrl = GetChannelUrl(context);

            if (string.IsNullOrWhiteSpace(channelUrl))
            {
                return(result);
            }

            try
            {
                using (var mgr = new UpdateManager(channelUrl))
                {
                    Log.Info($"Checking for updates using url '{channelUrl}'");

                    var updateInfo = await mgr.CheckForUpdate();

                    if (updateInfo.ReleasesToApply.Count > 0)
                    {
                        Log.Info($"Found new version '{updateInfo.FutureReleaseEntry?.Version}' using url '{channelUrl}', installing update...");

                        result.IsUpdateInstalledOrAvailable = true;
                        result.NewVersion = updateInfo.FutureReleaseEntry?.Version?.ToString();

                        UpdateInstalling?.Invoke(this, new SquirrelEventArgs(result));

                        var releaseEntry = await mgr.UpdateApp();

                        if (releaseEntry != null)
                        {
                            Log.Info("Update installed successfully");

                            result.NewVersion = releaseEntry.Version?.ToString();
                        }
                        else
                        {
                            Log.Warning("Update finished, but no release entry was returned, falling back to previous update info");
                        }

                        IsUpdatedInstalled = true;

                        UpdateInstalled?.Invoke(this, new SquirrelEventArgs(result));
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "An error occurred while checking for or installing the latest updates");
            }

            return(result);
        }
Beispiel #2
0
        private async Task ExecuteUpdateCheckLoop()
        {
            var current = GetCurrentLocalExe();
            var latest  = default(R1Executable);

            while (true)
            {
                Status = $"Checking for version newer than [{current.FileVersion}] ...";
                latest = await _updatr.GetLatestVersions();

                if (current.FileHash == latest.FileHash)
                {
                    Status = $"Nothing new.  Will check again in {_intervalMins} minutes ...";
                    await Task.Delay(1000 *_intervalMins * 60);
                }
                else
                {
                    Status = $"Newer version found: [{latest.FileVersion}]. Downloading ...";
                    if (await DownloadAndSwap(latest))
                    {
                        UpdateInstalled?.Raise(this);
                        Status = "Updates downloaded and installed.  Ready to relaunch.";
                        return;
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Handles the updates by installing them if there is an update available.
        /// </summary>
        /// <param name="maximumReleaseDate">The maximum release date.</param>
        /// <returns>Task.</returns>
        public async Task HandleUpdatesAsync(DateTime?maximumReleaseDate = null)
        {
            if (!_initialized)
            {
                throw Log.ErrorAndCreateException <InvalidOperationException>("Service is not initialized, call Initialize first");
            }

            var checkForUpdates = _configurationService.GetValue <bool>(Settings.Application.AutomaticUpdates.CheckForUpdates);

            if (!checkForUpdates)
            {
                Log.Info("Automatic updates are disabled");
                return;
            }

            var channelName            = _configurationService.GetValue <string>(Settings.Application.AutomaticUpdates.UpdateChannel, string.Empty);
            var channelUrlSettingsName = Settings.Application.AutomaticUpdates.GetChannelSettingName(channelName);
            var channelUrl             = _configurationService.GetValue <string>(channelUrlSettingsName, string.Empty);

            if (string.IsNullOrEmpty(channelUrl))
            {
                Log.Warning("Cannot find url for channel '{0}'", channelName);
                return;
            }

            var entryAssemblyDirectory = AssemblyHelper.GetEntryAssembly().GetDirectory();
            var updateExe = GetUpdateExecutable();

            if (!File.Exists(updateExe))
            {
                Log.Warning("Cannot check for updates, update.exe is not available");
                return;
            }

            Log.Info("Calling update.exe for url '{0}'", channelUrl);

            await TaskHelper.Run(() =>
            {
                try
                {
                    if (!maximumReleaseDate.HasValue)
                    {
                        maximumReleaseDate = DateTime.MaxValue;
                    }

                    var startInfo              = new ProcessStartInfo(updateExe);
                    startInfo.Arguments        = string.Format("--update={0} --md={1} --silent", channelUrl, maximumReleaseDate.Value.ToString("yyyyMMddHHmmss"));
                    startInfo.WorkingDirectory = Path.GetFullPath("..", entryAssemblyDirectory);
                    startInfo.UseShellExecute  = true;
                    startInfo.CreateNoWindow   = true;

                    var process = Process.Start(startInfo);
                    process.WaitForExit();

                    Log.Debug("Update.exe exited with exit code '{0}'", process.ExitCode);

                    // Possible exit codes:
                    // -1 => An error occurred. Check the log file for more information about this error
                    //  0 => No errors, no additional information available
                    //  1 => New version available or new version is installed successfully (depending on switch /checkonly)
                    //  2 => New version which is mandatory (forced) is available (for the future?)
                    //  3 => No new version available

                    switch (process.ExitCode)
                    {
                    case 1:
                        IsUpdatedInstalled = true;
                        UpdateInstalled.SafeInvoke(this);

                        Log.Info("Installed new update");
                        break;

                    case 4:
                        IsUpdateOutsideMaintenanceAvailable = true;
                        UpdateOutsideMaintenanceAvailable.SafeInvoke(this);

                        Log.Info("New update is available but is outside maintenance, maintenance ended on '{0}'", maximumReleaseDate);
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Failed to check for updates");
                }
            }, true);
        }
Beispiel #4
0
        /// <summary>
        /// Installes the available updates if there is an update available.
        /// </summary>
        /// <returns>Task.</returns>
        public async Task <SquirrelResult> InstallAvailableUpdatesAsync(SquirrelContext context)
        {
            Argument.IsNotNull(() => context);

            var result = new SquirrelResult
            {
                IsUpdateInstalledOrAvailable = false,
                CurrentVersion = GetCurrentApplicationVersion()
            };

            var channelUrl = GetChannelUrl(context);

            if (string.IsNullOrWhiteSpace(channelUrl))
            {
                return(result);
            }

            try
            {
                // Do we actually have an update? Do a quick one here
                var checkResult = await CheckForUpdatesAsync(context);

                // Note that we don't want the process to stop updating, we only want to invoke
                if (checkResult.IsUpdateInstalledOrAvailable)
                {
                    Log.Info($"Found new version '{checkResult.NewVersion}' using url '{channelUrl}', installing update...");

                    result.NewVersion = checkResult.NewVersion;

                    UpdateInstalling?.Invoke(this, new SquirrelEventArgs(result));
                }
                else
                {
                    Log.Info($"Could not determine whether a new version was available for certain, going to run update anyway...");
                }

                // Executable wrapper
                var startInfo = CreateUpdateProcessStartInfo($"--update={channelUrl}");
                var process   = Process.Start(startInfo);

                var line = "0";

                while (!string.IsNullOrWhiteSpace(line))
                {
                    if (int.TryParse(line, out var progress))
                    {
                        RaiseProgressChanged(progress);
                    }

                    line = await process.StandardOutput.ReadLineAsync();
                }

                process.WaitForExit();

                // Only when we knew there was an update pending, we notify
                if (process.ExitCode == 0 && checkResult.IsUpdateInstalledOrAvailable)
                {
                    result.NewVersion = checkResult?.NewVersion ?? "unknown";
                    result.IsUpdateInstalledOrAvailable = true;

                    Log.Info("Update installed successfully");

                    IsUpdatedInstalled = true;

                    UpdateInstalled?.Invoke(this, new SquirrelEventArgs(result));

                    Log.Info("Update installed successfully");
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "An error occurred while checking for or installing the latest updates");
            }

            return(result);
        }