/// <inheritdoc/> public virtual ICheckingForUpdates ShowCheckingForUpdates(SparkleUpdater sparkle) { return(new CheckingForUpdatesWindow(_iconBitmap) { Icon = _applicationIcon }); }
/// <inheritdoc/> public virtual IDownloadProgress CreateProgressWindow(SparkleUpdater sparkle, AppCastItem item) { return(new DownloadProgressWindow(item, _applicationIcon) { SoftwareWillRelaunchAfterUpdateInstalled = sparkle.RelaunchAfterUpdate }); }
public MainWindow() { InitializeComponent(); // remove the netsparkle key from registry try { Microsoft.Win32.Registry.CurrentUser.DeleteSubKeyTree("Software\\Microsoft\\NetSparkle.TestAppWPF"); } catch { } // set icon in project properties! string manifestModuleName = System.Reflection.Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName; var icon = System.Drawing.Icon.ExtractAssociatedIcon(manifestModuleName); _sparkle = new SparkleUpdater("https://netsparkleupdater.github.io/NetSparkle/files/sample-app/appcast.xml", new DSAChecker(Enums.SecurityMode.Strict)) { UIFactory = new NetSparkleUpdater.UI.WPF.UIFactory(NetSparkleUpdater.UI.WPF.IconUtilities.ToImageSource(icon)), ShowsUIOnMainThread = false, //RelaunchAfterUpdate = true, //UseNotificationToast = true }; // TLS 1.2 required by GitHub (https://developer.github.com/changes/2018-02-01-weak-crypto-removal-notice/) _sparkle.SecurityProtocolType = System.Net.SecurityProtocolType.Tls12; _sparkle.StartLoop(true, true); }
public MainWindow() { InitializeComponent(); this.AttachDevTools(); this.PropertyChanged += (s, e) => { if (e.Property == Control.DataContextProperty) { ctx = (MainWindowViewModel)e.NewValue !; ctx.OnUpdateAction = ManualUpdate_Click; } }; Closing += (sender, args) => MainViewClosing?.Invoke(sender, args); InputManager.Instance.PreProcess.OfType <RawInputEventArgs>() .Throttle(TimeSpan.FromMilliseconds(500)) .Subscribe( (_) => { if (_inactivityControlEnabled && _activityTimer != null) { _activityTimer.Stop(); _activityTimer.Start(); } }); _sparkle = new SparkleUpdater( "https://github.com/atomex-me/atomex.client.desktop/releases/latest/download/appcast.xml", new Ed25519Checker(SecurityMode.OnlyVerifySoftwareDownloads, "76FH2gIo7D5mpPPfnard5C9cVwq8TFaxpo/Wi2Iem/E=")) { UserInteractionMode = UserInteractionMode.DownloadNoInstall }; _sparkle.LogWriter = new SparkleLogger(); _sparkle.SecurityProtocolType = System.Net.SecurityProtocolType.Tls12; _sparkle.StartLoop(false, false); CheckForUpdates(null, null); var checkUpdateReadyTimer = new Timer(TimeSpan.FromMinutes(5).TotalMilliseconds); checkUpdateReadyTimer.AutoReset = true; checkUpdateReadyTimer.Elapsed += CheckForUpdates; checkUpdateReadyTimer.Start(); _sparkle.DownloadStarted += (item, path) => { Console.WriteLine($"Updating download started {path}"); }; _sparkle.DownloadFinished += (item, path) => { Console.WriteLine($"Updating download finished ${path}"); ctx.UpdateDownloadProgress = 100; }; _sparkle.DownloadMadeProgress += (sender, item, args) => { ctx.UpdateDownloadProgress = (int)((double)args.BytesReceived / (double)args.TotalBytesToReceive * 100); }; }
public UpdateManager() { _sparkle = new SparkleUpdater("https://timschneeberger.me/updates/galaxybudsclient/appcast.xml", new Ed25519Checker(SecurityMode.Unsafe)) { SecurityProtocolType = System.Net.SecurityProtocolType.Tls12 }; _sparkle.StartLoop(false, false); }
public SGAppUpdaterService() { SparkleInst = new SparkleUpdater("https://netsparkleupdater.github.io/NetSparkle/files/sample-app/appcast.xml", new DSAChecker(SecurityMode.Strict)) { UIFactory = null, }; // TLS 1.2 required by GitHub (https://developer.github.com/changes/2018-02-01-weak-crypto-removal-notice/) SparkleInst.SecurityProtocolType = System.Net.SecurityProtocolType.Tls12; }
/// <summary> /// Base constructor for ReleaseNotesGrabber /// </summary> /// <param name="separatorTemplate">Template to use for separating each item in the HTML</param> /// <param name="htmlHeadAddition">Any additional header information to stick in the HTML that will show up in the release notes</param> /// <param name="sparkle">Sparkle updater being used</param> public ReleaseNotesGrabber(string separatorTemplate, string htmlHeadAddition, SparkleUpdater sparkle) { _separatorTemplate = !string.IsNullOrEmpty(separatorTemplate) ? separatorTemplate : "<div style=\"border: #ccc 1px solid;\"><div style=\"background: {3}; padding: 5px;\"><span style=\"float: right; display:float;\">" + "{1}</span>{0}</div><div style=\"padding: 5px;\">{2}</div></div><br>"; _initialHTML = "<html><head><meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>" + htmlHeadAddition + "</head><body>"; _sparkle = sparkle; ChecksReleaseNotesSignature = false; }
/// <summary> /// Base constructor for ReleaseNotesGrabber /// </summary> /// <param name="releaseNotesTemplate">Template to use for separating each item in the HTML</param> /// <param name="htmlHeadAddition">Any additional header information to stick in the HTML that will show up in the release notes</param> /// <param name="sparkle">Sparkle updater being used</param> public ReleaseNotesGrabber(string releaseNotesTemplate, string htmlHeadAddition, SparkleUpdater sparkle) { ReleaseNotesTemplate = !string.IsNullOrEmpty(releaseNotesTemplate) ? releaseNotesTemplate : "<div style=\"border: #ccc 1px solid;\"><div style=\"background: {3}; padding: 5px;\"><span style=\"float: right;\">" + "{1}</span>{0}</div><div style=\"padding: 5px;\">{2}</div></div><br/>"; AdditionalHeaderHTML = htmlHeadAddition; _sparkle = sparkle; ChecksReleaseNotesSignature = false; LoadingHTML = "<p><em>Loading release notes...</em></p>"; }
/// <inheritdoc/> public virtual IDownloadProgress CreateProgressWindow(SparkleUpdater sparkle, AppCastItem item) { var viewModel = new DownloadProgressWindowViewModel() { ItemToDownload = item, SoftwareWillRelaunchAfterUpdateInstalled = sparkle.RelaunchAfterUpdate }; return(new DownloadProgressWindow(viewModel, _iconBitmap) { Icon = _applicationIcon }); }
/// <inheritdoc/> public virtual void ShowToast(SparkleUpdater sparkle, List <AppCastItem> updates, Action <List <AppCastItem> > clickHandler) { Thread thread = new Thread(() => { var toast = new ToastNotifier(_applicationIcon) { ClickAction = clickHandler, Updates = updates }; toast.Show(Resources.DefaultUIFactory_ToastMessage, Resources.DefaultUIFactory_ToastCallToAction, 5); Application.Run(toast); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); }
public virtual IUpdateAvailable CreateAllReleaseDownloadList(SparkleUpdater sparkle, List <AppCastItem> updates, bool isUpdateAlreadyDownloaded, bool isforallversions = false) { var window = new UpdateAvailableWindow(sparkle, updates, _applicationIcon, isUpdateAlreadyDownloaded, "", "", isforallversions); if (HideReleaseNotes) { (window as IUpdateAvailable).HideReleaseNotes(); } if (HideSkipButton) { (window as IUpdateAvailable).HideSkipButton(); } if (HideRemindMeLaterButton) { (window as IUpdateAvailable).HideRemindMeLaterButton(); } return(window); }
/// <inheritdoc/> public virtual IUpdateAvailable CreateUpdateAvailableWindow(SparkleUpdater sparkle, List <AppCastItem> updates, bool isUpdateAlreadyDownloaded = false) { var window = new UpdateAvailableWindow(sparkle, updates, _applicationIcon, isUpdateAlreadyDownloaded, ReleaseNotesHTMLTemplate, AdditionalReleaseNotesHeaderHTML); if (HideReleaseNotes) { (window as IUpdateAvailable).HideReleaseNotes(); } if (HideSkipButton) { (window as IUpdateAvailable).HideSkipButton(); } if (HideRemindMeLaterButton) { (window as IUpdateAvailable).HideRemindMeLaterButton(); } return(window); }
public MainWindow() { InitializeComponent(); #if DEBUG this.AttachDevTools(); #endif // set icon in project properties! string manifestModuleName = System.Reflection.Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName; _sparkle = new SparkleUpdater("https://netsparkleupdater.github.io/NetSparkle/files/sample-app/appcast.xml", new DSAChecker(Enums.SecurityMode.Strict)) { UIFactory = new NetSparkleUpdater.UI.Avalonia.UIFactory(Icon), // Avalonia version doesn't support separate threads: https://github.com/AvaloniaUI/Avalonia/issues/3434#issuecomment-573446972 ShowsUIOnMainThread = true, //UseNotificationToast = false // Avalonia version doesn't yet support notification toast messages }; // TLS 1.2 required by GitHub (https://developer.github.com/changes/2018-02-01-weak-crypto-removal-notice/) _sparkle.SecurityProtocolType = System.Net.SecurityProtocolType.Tls12; _sparkle.StartLoop(true, true); }
public Form1() { InitializeComponent(); var appcastUrl = "https://netsparkleupdater.github.io/NetSparkle/files/sample-app/appcast.xml"; // set icon in project properties! string manifestModuleName = System.Reflection.Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName; var icon = System.Drawing.Icon.ExtractAssociatedIcon(manifestModuleName); _sparkleUpdateDetector = new SparkleUpdater(appcastUrl, new DSAChecker(Enums.SecurityMode.Strict)) { UIFactory = new NetSparkleUpdater.UI.WinForms.UIFactory(icon), //RelaunchAfterUpdate = true, //ShowsUIOnMainThread = true, //UseNotificationToast = true }; // TLS 1.2 required by GitHub (https://developer.github.com/changes/2018-02-01-weak-crypto-removal-notice/) _sparkleUpdateDetector.SecurityProtocolType = System.Net.SecurityProtocolType.Tls12; //_sparkleUpdateDetector.CloseApplication += _sparkleUpdateDetector_CloseApplication; _sparkleUpdateDetector.StartLoop(true, true); }
public MainWindow() { InitializeComponent(); try { Microsoft.Win32.Registry.CurrentUser.DeleteSubKeyTree("Software\\Microsoft\\NetSparkle.TestAppNetCoreWPF"); } catch { } // get sparkle ready DownloadUpdateButton.IsEnabled = false; InstallUpdateButton.IsEnabled = false; _sparkle = new SparkleUpdater("https://netsparkleupdater.github.io/NetSparkle/files/sample-app/appcast.xml", new DSAChecker(Enums.SecurityMode.Strict)) { UIFactory = null, }; // TLS 1.2 required by GitHub (https://developer.github.com/changes/2018-02-01-weak-crypto-removal-notice/) _sparkle.SecurityProtocolType = System.Net.SecurityProtocolType.Tls12; }
private static void Internal_SetupSparkle() { if (_sparkle == null) { _sparkle = new SparkleUpdater(APP_CAST_XML, new DSAChecker(NetSparkleUpdater.Enums.SecurityMode.UseIfPossible, "+mLdLTe3Mj6OU0Kr6+ZDeVj+TTFRsNUJvUaPhuJ7pUI=")) { ShowsUIOnMainThread = false, UseNotificationToast = true }; _sparkle.LogWriter = new LogWriter(true); } if (_sparkle.UIFactory == null) { string manifestModuleName = System.Reflection.Assembly.GetEntryAssembly().ManifestModule.FullyQualifiedName; var icon = System.Drawing.Icon.ExtractAssociatedIcon(manifestModuleName); _sparkle.UIFactory = new NetSparkleUpdater.UI.WPF.UIFactory(NetSparkleUpdater.UI.WPF.IconUtilities.ToImageSource(icon)); } _sparkle.SecurityProtocolType = System.Net.SecurityProtocolType.Tls12; }
/// <inheritdoc/> public virtual IUpdateAvailable CreateUpdateAvailableWindow(SparkleUpdater sparkle, List <AppCastItem> updates, bool isUpdateAlreadyDownloaded = false) { var viewModel = new UpdateAvailableWindowViewModel(); var window = new UpdateAvailableWindow(viewModel, _iconBitmap) { Icon = _applicationIcon }; if (HideReleaseNotes) { (window as IUpdateAvailable).HideReleaseNotes(); } if (HideSkipButton) { (window as IUpdateAvailable).HideSkipButton(); } if (HideRemindMeLaterButton) { (window as IUpdateAvailable).HideRemindMeLaterButton(); } viewModel.Initialize(sparkle, updates, isUpdateAlreadyDownloaded, ReleaseNotesHTMLTemplate, AdditionalReleaseNotesHeaderHTML); return(window); }
/// <inheritdoc/> public virtual void ShowToast(SparkleUpdater sparkle, List <AppCastItem> updates, Action <List <AppCastItem> > clickHandler) { Thread thread = new Thread(() => { var toast = new ToastNotification() { ClickAction = clickHandler, Updates = updates, Icon = _applicationIcon }; try { toast.Show(Resources.DefaultUIFactory_ToastMessage, Resources.DefaultUIFactory_ToastCallToAction, 5); System.Windows.Threading.Dispatcher.Run(); } catch (ThreadAbortException) { toast.Dispatcher.InvokeShutdown(); } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); }
/// <inheritdoc/> public virtual void ShowDownloadErrorMessage(SparkleUpdater sparkle, string message, string appcastUrl) { ShowMessage(Resources.DefaultUIFactory_ErrorTitle, string.Format(Resources.DefaultUIFactory_ShowDownloadErrorMessage, message)); }
public UpdateAvailableDialog(SparkleUpdater sparkle, List <AppCastItem> items, Icon applicationIcon = null, bool isUpdateAlreadyDownloaded = false, string separatorTemplate = "", string headAddition = "") { _sparkle = sparkle; _updates = items; _releaseNotesGrabber = new ReleaseNotesGrabber(separatorTemplate, headAddition, sparkle); InitializeComponent(); // init ui try { wbChangeLog.AllowWebBrowserDrop = false; wbChangeLog.AllowNavigation = false; } catch (Exception ex) { _sparkle.LogWriter.PrintMessage("Error in browser init: {0}", ex.Message); } AppCastItem item = items.FirstOrDefault(); var downloadInstallText = isUpdateAlreadyDownloaded ? "install" : "download"; klblHeader.Text = $"A new version of { item.AppName } is available!"; if (item != null) { var versionString = ""; try { // Use try/catch since Version constructor can throw an exception and we don't want to // die just because the user has a malformed version string Version versionObj = new Version(item.AppVersionInstalled); versionString = Utilities.GetVersionString(versionObj); } catch { versionString = "?"; } klblInfo.Text = string.Format("{0} {3} is now available (you have {1}). Would you like to {2} it now?", item.AppName, versionString, downloadInstallText, item.Version); } else { // TODO: string translations (even though I guess this window should never be called with 0 app cast items...) klblInfo.Text = string.Format("Would you like to {0} it now?", downloadInstallText); } bool isUserMissingCriticalUpdate = items.Any(x => x.IsCriticalUpdate); kbtnRemindLater.Enabled = isUserMissingCriticalUpdate == false; kbtnSkip.Enabled = isUserMissingCriticalUpdate == false; //if (isUserMissingCriticalUpdate) //{ // FormClosing += UpdateAvailableWindow_FormClosing; // no closing a critical update! //} if (applicationIcon != null) { using (Icon icon = new Icon(applicationIcon, new Size(48, 48))) { pbxApplicationIcon.Image = icon.ToBitmap(); } Icon = applicationIcon; } _cancellationTokenSource = new CancellationTokenSource(); _cancellationToken = _cancellationTokenSource.Token; wbChangeLog.DocumentText = _releaseNotesGrabber.GetLoadingText(); EnsureDialogShown(); LoadReleaseNotes(items); }
/// <inheritdoc/> public virtual void ShowUnknownInstallerFormatMessage(SparkleUpdater sparkle, string downloadFileName) { ShowMessage(Resources.DefaultUIFactory_MessageTitle, string.Format(Resources.DefaultUIFactory_ShowUnknownInstallerFormatMessageText, downloadFileName)); }
/// <summary> /// Download the release notes at the given link. Does not do anything else /// for the release notes (verification, display, etc.) -- just downloads the /// release notes and passes them back as a string. /// </summary> /// <param name="link">string URL to the release notes to download</param> /// <param name="cancellationToken">token that can be used to cancel a download operation</param> /// <param name="sparkle"><see cref="SparkleUpdater"/> that can be used for logging information /// about the download process (or its failures)</param> /// <returns></returns> protected virtual async Task <string> DownloadReleaseNotes(string link, CancellationToken cancellationToken, SparkleUpdater sparkle) { try { using (var webClient = new WebClient()) { webClient.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials; webClient.Encoding = Encoding.UTF8; if (cancellationToken != null) { using (cancellationToken.Register(() => webClient.CancelAsync())) { return(await webClient.DownloadStringTaskAsync(Utilities.GetAbsoluteURL(link, sparkle.AppCastUrl))); } } return(await webClient.DownloadStringTaskAsync(Utilities.GetAbsoluteURL(link, sparkle.AppCastUrl))); } } catch (WebException ex) { sparkle.LogWriter.PrintMessage("Cannot download release notes from {0} because {1}", link, ex.Message); return(""); } }
/// <summary> /// Grab the release notes for the given item and return their release notes /// in HTML format so that they can be displayed to the user. /// </summary> /// <param name="item"><see cref="AppCastItem"/>item to download the release notes for</param> /// <param name="sparkle"><see cref="SparkleUpdater"/> that can be used for logging information /// about the release notes grabbing process (or its failures)</param> /// <param name="cancellationToken">token that can be used to cancel a release notes /// grabbing operation</param> /// <returns></returns> protected virtual async Task <string> GetReleaseNotes(AppCastItem item, SparkleUpdater sparkle, CancellationToken cancellationToken) { string criticalUpdate = item.IsCriticalUpdate ? "Critical Update" : ""; // at first try to use embedded description if (!string.IsNullOrEmpty(item.Description)) { // check for markdown Regex containsHtmlRegex = new Regex(@"<\s*([^ >]+)[^>]*>.*?<\s*/\s*\1\s*>"); if (containsHtmlRegex.IsMatch(item.Description)) { if (item.IsCriticalUpdate) { item.Description = "<p><em>" + criticalUpdate + "</em></p>" + "<br>" + item.Description; } return(item.Description); } else { var md = new Markdown(); if (item.IsCriticalUpdate) { item.Description = "*" + criticalUpdate + "*" + "\n\n" + item.Description; } var temp = md.Transform(item.Description); return(temp); } } // not embedded so try to release notes from the link if (string.IsNullOrEmpty(item.ReleaseNotesLink)) { return(null); } // download release notes sparkle.LogWriter.PrintMessage("Downloading release notes for {0} at {1}", item.Version, item.ReleaseNotesLink); string notes = await DownloadReleaseNotes(item.ReleaseNotesLink, cancellationToken, sparkle); sparkle.LogWriter.PrintMessage("Done downloading release notes for {0}", item.Version); if (string.IsNullOrEmpty(notes)) { return(null); } // check dsa of release notes if (!string.IsNullOrEmpty(item.ReleaseNotesSignature)) { if (ChecksReleaseNotesSignature && _sparkle.SignatureVerifier != null && Utilities.IsSignatureNeeded(_sparkle.SignatureVerifier.SecurityMode, _sparkle.SignatureVerifier.HasValidKeyInformation()) && sparkle.SignatureVerifier.VerifySignatureOfString(item.ReleaseNotesSignature, notes) == ValidationResult.Invalid) { return(null); } } // process release notes var extension = Path.GetExtension(item.ReleaseNotesLink); if (extension != null && MarkdownExtensions.Contains(extension.ToLower())) { try { var md = new Markdown(); if (item.IsCriticalUpdate) { notes = "*" + criticalUpdate + "*" + "\n\n" + notes; } notes = md.Transform(notes); } catch (Exception ex) { sparkle.LogWriter.PrintMessage("Error parsing Markdown syntax: {0}", ex.Message); } } return(notes); }
/// <inheritdoc/> public virtual void ShowVersionIsUpToDate(SparkleUpdater sparkle) { ShowMessage(Resources.DefaultUIFactory_MessageTitle, Resources.DefaultUIFactory_ShowVersionIsUpToDateMessage); }
/// <inheritdoc/> public virtual void ShowVersionIsSkippedByUserRequest(SparkleUpdater sparkle) { ShowMessage(Resources.DefaultUIFactory_MessageTitle, Resources.DefaultUIFactory_ShowVersionIsSkippedByUserRequestMessage); }
/// <inheritdoc/> public virtual void Init(SparkleUpdater sparkle) { // enable visual style to ensure that we have XP style or higher // also in WPF applications Application.EnableVisualStyles(); }
/// <inheritdoc/> public virtual ICheckingForUpdates ShowCheckingForUpdates(SparkleUpdater sparkle) { return(new CheckingForUpdatesWindow(_applicationIcon)); }
/// <inheritdoc/> public virtual void ShowCannotDownloadAppcast(SparkleUpdater sparkle, string appcastUrl) { ShowMessage(Resources.DefaultUIFactory_ErrorTitle, Resources.DefaultUIFactory_ShowCannotDownloadAppcastMessage); }
/// <inheritdoc/> public virtual bool CanShowToastMessages(SparkleUpdater sparkle) { return(true); }
/// <inheritdoc/> public void Shutdown(SparkleUpdater sparkle) { Application.Exit(); }