NetSparkle Software Update Framework

repository·develop·Indexed 21 days ago

https://github.com/netsparkleupdater/netsparkle

A highly-configurable software update framework for C# .NET projects supporting .NET 6+ and .NET Framework 4.6.2+. It provides built-in UIs for WinForms, WPF, and Avalonia, and supports custom update flows using cryptographic signatures. The framework includes the SparkleUpdater core and CLI tools like the App Cast Generator (netsparkle-generate-appcast) and DSA Helper (netsparkle-dsa) to manage update manifests and Ed25519 keys.

Tokens
10K
Snippets
22
Records
43
Agent score
73%

What's inside NetSparkle

  1. Handle critical updates in NetSparkle

    develop

    NetSparkle supports marking updates as critical via the sparkle:criticalUpdate="true" attribute in the appcast <enclosure> tag.

    When an update is marked as critical:

    1. The 'Skip' and 'Remind Me Later' buttons are disabled in the UI.
    2. The release notes for that version will state that the update is critical.

    To programmatically detect if an update is critical, check Sparkle.LatestAppCastItems or the Sparkle.UpdateMarkedCritical property.

  2. Filter AppCast items by Channel

    develop

    NetSparkle 3.x provides ChannelAppCastFilter to easily filter app cast items by a specific channel (e.g., beta, alpha, or preview). This is useful for allowing users to opt-in to specific update tracks.

    To use it, set the AppCastHelper.AppCastFilter property on your SparkleUpdater instance.

    Configuration Options

    • ChannelSearchNames: A List<string> of channel names to search for (e.g., new List<string>() {"beta"}). It uses a simple string.Contains invariant lowercase check.
    • RemoveOlderItems: If true, it removes items that don't match the channel. If false, it keeps old versions (useful for rollbacks).
    • KeepItemsWithNoChannelInfo: If false, it removes all items that do not match the specified channel. Warning: Setting this to false may prevent users on a beta version from updating to a non-beta version.
    // Example setup for a beta channel filter
    var filter = new ChannelAppCastFilter
    {
        ChannelSearchNames = new List<string> { "beta" },
        RemoveOlderItems = true,
        KeepItemsWithNoChannelInfo = false
    };
    
    // Apply to the helper
    sparkleUpdater.AppCastHelper.AppCastFilter = filter;
  3. Extend NetSparkle via Interfaces

    develop

    NetSparkle is highly extensible through several key interfaces. You can implement these to provide custom UI, networking, or logic:

    UI Customization

    • IUIFactory: The primary way to provide your own UI. It manages the creation of windows for checking updates, download progress, and available updates.
    • ICheckingForUpdates: Interface for UI to show 'Checking...' status.
    • IDownloadProgress: Interface for UI to show download progress.
    • IUpdateAvailable: Interface for UI to show update details and release notes.

    Data and Networking

    • IAppCastDataDownloader: Control how the app cast file is downloaded (e.g., WebRequestAppCastDataDownloader for web, LocalFileAppCastDownloader for local files).
    • IAppCastFilter: Filter AppCastItem objects (e.g., using ChannelAppCastFilter to filter by alpha/beta channels).
    • IAppCastGenerator: Control serialization/deserialization (e.g., XMLAppCastGenerator, JsonAppCastGenerator).
    • IUpdateDownloader: Control how the actual update files (installers) are downloaded (e.g., WebFileDownloader).

    System and Security

    • IAssemblyAccessor: Control how version and product metadata is loaded.
    • ILogger: Implement to redirect NetSparkle logs to your own logging system.
    • ISignatureVerifier: Implement to change how signatures are validated.

    Configuration and Subclassing

    • Configuration: Subclass this to change where data is saved (e.g., RegistryConfiguration for Windows, JSONConfiguration for macOS/Linux).
    • AppCastHelper: Subclass for absolute control over the downloading and parsing process.
    • ReleaseNotesGrabber: Subclass to control how release notes are fetched and displayed.
  4. How App Casts work in NetSparkle

    develop

    An app cast is an XML or JSON file containing product metadata and release definitions. NetSparkle reads <item> tags to identify available updates.

    Key App Cast Elements

    • <description>: HTML or Markdown description of the update. Overrides <sparkle:releaseNotesLink>.
    • <sparkle:releaseNotesLink>: URL to an HTML/Markdown document. Can be signed via sparkle:signature.
    • <pubDate>: Publication date.
    • sparkle:channel: Release channel (e.g., beta).
    • <enclosure>: Defines the update file. Important attributes:
      • url: Download URL.
      • sparkle:version: Machine-readable version.
      • sparkle:signature: DSA/Ed25519 signature of the file.
      • sparkle:criticalUpdate: If true or 1, the UI flags it as critical.
      • sparkle:os: Target OS (windows, macos, or linux).

    Security Requirements

    For SecurityMode.Strict, you need two signatures:

    1. Enclosure Signature: A signature for the update file itself (sparkle:signature).
    2. App Cast Signature: A signature for the app cast file, located at [AppCastURL].signature (e.g., http://example.com/appcast.xml.signature).
    <?xml version="1.0" encoding="UTF-8"?>
    <rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
        <channel>
            <title>NetSparkle Test App</title>
            <link>https://netsparkleupdater.github.io/NetSparkle/files/sample-app/appcast.xml</link>
            <description>Most recent changes with links to updates.</description>
            <language>en</language>
            <item>
                <title>Version 2.0 (2 bugs fixed; 3 new features)</title>
                <sparkle:releaseNotesLink>
                https://netsparkleupdater.github.io/NetSparkle/files/sample-app/2.0-release-notes.md
                </sparkle:releaseNotesLink>
                <pubDate>Thu, 27 Oct 2016 10:30:00 +0000</pubDate>
                <enclosure url="https://netsparkleupdater.github.io/NetSparkle/files/sample-app/NetSparkleUpdate.exe"
                           sparkle:version="2.0"
                           sparkle:os="windows"
                           length="12288"
                           type="application/octet-stream"
                           sparkle:signature="NSG/eKz9BaTJrRDvKSwYEaOumYpPMtMYRq+vjsNlHqRGku/Ual3EoQ==" />
            </item>
        </channel>
    </rss>
  5. Handle application exit and updates

    develop

    When implementing custom logic or a custom UI, you must manage the application lifecycle carefully:

    • Graceful Exit: Subscribe to PreparingToExit to allow the user to save work before the application closes.
    • Closing the App: If you are not using a UIFactory, you must use the CloseApplication or CloseApplicationAsync events to close your application. If you don't, the downloaded update file may never be executed.
    • Timeout: The process that launches the downloaded update executable waits for 90 seconds. Ensure your application closes within this window after the close event is called.
    _sparkle.PreparingToExit += ((x, cancellable) =>
    {
        // Ask user to save work, etc.
    });
  6. Implement a custom UI using IUIFactory

    develop

    In version 2.A and later, all UI elements (including icons, release notes visibility, and skip buttons) are managed via the IUIFactory interface. To use a custom UI, you must implement IUIFactory and pass it to the SparkleUpdater.

    Requirements for IUIFactory implementors:

    • Must implement ReleaseNotesHTMLTemplate and AdditionalReleaseNotesHeaderHTML (can be string.Empty, "", or null).
    • All IUIFactory methods receive a reference to the SparkleUpdater instance that triggered the call.

    UI Control Properties:

    • HideReleaseNotes, HideRemindMeLaterButton, and HideSkipButton are now handled by your IUIFactory implementation.
  7. Filter updates using channels

    develop

    You can restrict which updates are visible to users by using channels (e.g., 'alpha', 'beta').

    1. Set the channel in the App Cast: Use the --channel property in the netsparkle-generate-appcast CLI tool, or manually add <sparkle:channel>YourChannel</sparkle:channel> to the XML item (or "channel": "YourChannel" in JSON).
    2. Set the channel in the Project: Set the <Version> in your .csproj to a semver-compatible version including the channel (e.g., <Version>1.0.2-beta1</Version>).
    3. Filter in Code: Use the ChannelAppCastFilter by assigning it to AppCastHelper.AppCastFilter (or SparkleUpdater.AppCastHelper.AppCastFilter). Set ChannelSearchNames to the allowed channels and KeepItemsWithNoChannelInfo to true if you want to allow standard updates alongside channel-specific ones.
  8. Understand the NetSparkle update workflow

    develop

    NetSparkle facilitates the client-side portion of software updates. The typical lifecycle is:

    1. Packaging: You compile and package your application (e.g., using InnoSetup, NSIS, or dotnet-packaging).
    2. App Cast Creation: You create an app cast file containing version and update information.
    3. Distribution: You upload your application installers, the app cast file, and the appCast-file.signature to a web server.
    4. Detection: The client application uses NetSparkle to check the app cast file online.
    5. Notification: NetSparkle notifies the user of an available update and shows release notes.
    6. Download & Install: The user accepts the update; NetSparkle downloads the file and assists in the installation process (often requiring the user to close the application first).
  9. Configure Silent Mode for updates

    develop

    The SilentMode option allows you to control how much of the update process is automated and visible to the user.

    Available modes:

    • NotSilent: The normal update process with UI interaction.
    • DownloadAndInstall: Completely silent updates. Warning: This may be jarring to users as the software may quit to run the installer. Monitor AboutToExitForInstallerRun or AboutToExitForInstallerRunAsync to notify users.
    • DownloadNoInstall: Downloads the update silently, but does not install it. You must manually initiate the installation process. Monitor the DownloadedFileReady event to know when the file is ready, then call _sparkle.ShowUpdateNeededUI(true); to show the update window.
  10. Install the AppCast Generator Tool

    develop

    The netsparkle-generate-appcast tool is used to create and update your app cast (XML or JSON) files and manage Ed25519 signatures. It requires the .NET 6, 7, 8, or 9 Desktop Runtime.

    Install the tool globally using the dotnet CLI:

    dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator
  11. Quick Start Guide for NetSparkle

    develop

    To integrate NetSparkle into your application, follow these steps:

    1. Install NuGet Packages: Install a pre-built UI package (e.g., for WPF, WinForms, or Avalonia) or just the core package if building your own UI.
    2. Configure Project File: Ensure your .csproj contains necessary metadata like <Version>, <AssemblyVersion>, <Company>, and <Product>. To avoid git commit hashes appearing in your version string in .NET 8+, add <IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>.
    3. Install CLI Tool: Install the app cast generator tool via dotnet:
      dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator
    4. Generate Keys: Create Ed25519 keys for signing updates:
      netsparkle-generate-appcast --generate-keys
      # To view your keys:
      netsparkle-generate-appcast --export
    5. Initialize SparkleUpdater: Add the SparkleUpdater instance to your main UI thread (e.g., MainWindow).
    6. Generate App Cast: Use the CLI tool to generate your update manifest:
      netsparkle-generate-appcast -b binary/folder -p change/log/folder -u https://example.com/downloads -l https://example.com/downloads/changelogs
    7. Deploy: Upload the app cast and all signed update files (including .signature files) to your server.
    dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator
    
    # Generate keys
    netsparkle-generate-appcast --generate-keys
    # Export keys to console
    netsparkle-generate-appcast --export
    
    # Generate appcast
    netsparkle-generate-appcast -b binary/folder -p change/log/folder -u https://example.com/downloads -l https://example.com/downloads/changelogs
  12. Upgrade between major NetSparkle versions

    develop
    When moving between major versions of NetSparkle, there may be breaking changes or fixes that require manual intervention. Refer to the UPGRADING.md file in the repository for a detailed list of breaking changes and specific instructions for each major version transition.