/// <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); }
/// <summary> /// Checks for any available updates. /// </summary> /// <returns><c>true</c> if an update is available; otherwise <c>false</c>.</returns> public async Task <SquirrelResult> CheckForUpdatesAsync(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}'"); result.IsUpdateInstalledOrAvailable = true; result.NewVersion = updateInfo.FutureReleaseEntry?.Version?.ToString(); } } } catch (Exception ex) { Log.Error(ex, "An error occurred while checking for the latest updates"); } return(result); }
/// <summary> /// Gets the channel url for the specified context. /// </summary> /// <returns>The channel url or <c>null</c> if no channel is available.</returns> protected string GetChannelUrl(SquirrelContext context) { if (!_initialized) { throw Log.ErrorAndCreateException <InvalidOperationException>("Service is not initialized, call Initialize first"); } var checkForUpdates = _configurationService.GetRoamingValue <bool>(Settings.Application.AutomaticUpdates.CheckForUpdates); if (!checkForUpdates) { Log.Info("Automatic updates are disabled"); return(null); } var channelName = context.ChannelName ?? _configurationService.GetRoamingValue(Settings.Application.AutomaticUpdates.UpdateChannel, string.Empty); var channelUrlSettingsName = Settings.Application.AutomaticUpdates.GetChannelSettingName(channelName); var channelUrl = _configurationService.GetRoamingValue(channelUrlSettingsName, string.Empty); if (string.IsNullOrEmpty(channelUrl)) { Log.Warning("Cannot find url for channel '{0}'", channelName); return(null); } var entryAssemblyDirectory = AssemblyHelper.GetEntryAssembly().GetDirectory(); var updateExe = GetUpdateExecutable(); if (!_fileService.Exists(updateExe)) { Log.Warning("Cannot check for updates, update.exe is not available"); return(null); } return(channelUrl); }
/// <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); }
/// <summary> /// Checks for any available updates. /// </summary> /// <returns><c>true</c> if an update is available; otherwise <c>false</c>.</returns> public async Task <SquirrelResult> CheckForUpdatesAsync(SquirrelContext context) { Argument.IsNotNull(() => context); var result = new SquirrelResult { IsUpdateInstalledOrAvailable = false, CurrentVersion = GetCurrentApplicationVersion() }; var channelUrl = GetChannelUrl(context); if (string.IsNullOrWhiteSpace(channelUrl)) { return(result); } try { var startInfo = CreateUpdateProcessStartInfo($"--checkForUpdate={channelUrl}"); var process = Process.Start(startInfo); var output = await process.StandardOutput.ReadToEndAsync(); process.WaitForExit(); var startIndex = output.IndexOf("{"); if (startIndex > 0) { output = output.Substring(startIndex); } // Results similar to this: //{ // "currentVersion": "2.3.0-alpha1013", // "futureVersion": "2.3.0-alpha1094", // "releasesToApply": [ // { // "version": "2.3.0-alpha1039", // "releaseNotes": "" // }, // { // "version": "2.3.0-alpha1074", // "releaseNotes": "" // }, // { // "version": "2.3.0-alpha1094", // "releaseNotes": "" // } // ] //} if (!string.IsNullOrWhiteSpace(output)) { dynamic releaseInfo = JObject.Parse(output); foreach (var releaseToApply in releaseInfo.releasesToApply) { result.IsUpdateInstalledOrAvailable = true; result.NewVersion = releaseToApply.version; } } if (!result.IsUpdateInstalledOrAvailable) { Log.Info("No updates available"); } else { Log.Info($"Found new version '{result.NewVersion}' using url '{channelUrl}'"); } } catch (Exception ex) { Log.Error(ex, "An error occurred while checking for the latest updates"); } return(result); }