NetSparkle is a C# .NET update checker that allows you to easily download installer files and update your WinForms or C# WPF software. You provide, somewhere on the internet, an XML appcast with version information, along with release notes in Markdown or HTML format. This library then checks for an update in the background, shows the user the release notes, and offers to download the new installer. The original NetSparkle library can be found at dei79/netsparkle.
Now available on NuGet! Note that we will switch to the "official" NuGet eventually!
NetSparkle also offers a command line tool to automatically generate your appcast for you! It still needs a few more features to have feature parity with the macOS generate_appcast
tool, but it can still save you a lot of time. Check it out on NuGet!
All notable changes to this project will be documented in the changelog.
- Basic Usage
- Appcast
- Sparkle class
- License
- Requirements
- Other Options
I highly recommend checking out Squirrel.Windows, which is a more Chrome-like software updater. You could also check out WinSparkle, but there isn't a merged .NET binding yet.
_sparkle = new Sparkle(
"http://example.com/appcast.xml",
this.Icon,
SecurityMode.Strict,
"<DSAKeyValue>...</DSAKeyValue>",
);
_sparkle.CheckOnFirstApplicationIdle();
On the first Application.Idle event, your appcast.xml will be read and compared to the currently running version. If it's newer, the user will be notified with a little "toast" box if enabled, otherwise with the update dialog containing your release notes (if defined). The user can then ignore the update, ask to be reminded later, or download it now.
If you want to add a manual update in the background, do
_sparkle.CheckForUpdatesQuietly();
If you want to have a menu item for the user to check for updates, use
_sparkle.CheckForUpdatesAtUserRequest();
If you have files that need saving, subscribe to the AboutToExitForInstallerRun event:
_sparkle.AboutToExitForInstallerRun += ((x, cancellable) =>
{
// ask the user to save, whatever else is needed to close down gracefully
});
Warning!
The .bat file that launches your executable only waits for 90 seconds before giving up! Make sure that your software closes within 90 seconds of CloseApplication/CloseApplicationAsync being called if you implement those events! If you need an event that can be canceled, use AboutToExitForInstallerRun/AboutToExitForInstallerRunAsync.
NetSparkle uses Sparkle-compatible appcasts. Here is a sample appcast:
<?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://deadpikle.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://deadpikle.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://deadpikle.github.io/NetSparkle/files/sample-app/NetSparkleUpdate.exe"
sparkle:version="2.0"
length="12288"
type="application/octet-stream"
sparkle:dsaSignature="NSG/eKz9BaTJrRDvKSwYEaOumYpPMtMYRq+vjsNlHqRGku/Ual3EoQ==" />
</item>
</channel>
</rss>
NetSparkle reads the <item>
tags to determine whether updates are available.
The important tags in each <item>
are:
<description>
- A description of the update in HTML or Markdown.
- Overrides the
<sparkle:releaseNotesLink>
tag.
<sparkle:releaseNotesLink>
- The URL to an HTML or Markdown document describing the update.
- If the
<description>
tag is present, it will be used instead. - Attributes:
sparkle:dsaSignature
, optional: the DSA signature of the document; if present, notes will only be displayed if the DSA signature is valid
<pubDate>
- The date this update was published
<enclosure>
- This tag describes the update file that NetSparkle will download.
- Attributes:
url
: URL of the update filesparkle:version
: machine-readable version number of this updatelength
, optional: (not validated) size of the update file in bytestype
: ignoredsparkle:dsaSignature
: DSA signature of the update filesparkle:criticalUpdate
, optional: if equal totrue
or1
, the UI will indicate that this is a critical update
By default, you need 2 DSA signatures (DSA Strict mode):
- One in the enclosure tag for your download file (
sparkle:dsaSignature="..."
) - Another on your web server to secure the actual appcast file. This file must be located at [CastURL].dsa. In other words, if the appcast URL is http://example.com/awesome-software.xml, you need a valid DSA signature for that file at http://example.com/awesome-software.xml.dsa.
- Sparkle(string appcastUrl)
- Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon)
- Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon, NetSparkle.SecurityMode securityMode)
- Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon, NetSparkle.SecurityMode securityMode, string dsaPublicKey)
- Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon, NetSparkle.SecurityMode securityMode, string dsaPublicKey, string referenceAssembly)
- Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon, NetSparkle.SecurityMode securityMode, string dsaPublicKey, string referenceAssembly, NetSparkle.Interfaces.IUIFactory factory)
- void CancelFileDownload()
- Task<NetSparkle.SparkleUpdateInfo> CheckForUpdatesAtUserRequest()
- Task<NetSparkle.SparkleUpdateInfo> CheckForUpdatesQuietly()
- void CheckOnFirstApplicationIdle()
- void Dispose()
- System.Uri GetAbsoluteUrl(string)
- NetSparkle.Configuration GetApplicationConfig()
- Task<NetSparkle.SparkleUpdateInfo> GetUpdateStatus(NetSparkle.Configuration config)
- System.Net.WebResponse GetWebContentResponse(string url)
- System.IO.Stream GetWebContentStream(string url)
- void ShowUpdateNeededUI(bool isUpdateAlreadyDownloaded)
- void ShowUpdateNeededUI(NetSparkle.AppCastItem[], bool)
- void StartLoop(bool doInitialCheck)
- void StartLoop(bool doInitialCheck, bool forceInitialCheck)
- void StartLoop(bool doInitialCheck, bool forceInitialCheck, System.TimeSpan checkFrequency)
- void StartLoop(bool doInitialCheck, System.TimeSpan checkFrequency)
- void StopLoop()
Initializes a new instance of the Sparkle class with the given appcast URL.
Name | Description |
---|---|
appcastUrl | System.String the URL of the appcast file |
Initializes a new instance of the Sparkle class with the given appcast URL and an Icon for the update UI.
Name | Description |
---|---|
appcastUrl | System.String the URL of the appcast file |
applicationIcon | System.Drawing.Icon Icon to be displayed in the update UI. If you're invoking this from a form, this would be this.Icon . |
Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon, NetSparkle.SecurityMode securityMode)
Initializes a new instance of the Sparkle class with the given appcast URL, an Icon for the update UI, and the security mode for DSA signatures.
Name | Description |
---|---|
appcastUrl | System.String the URL of the appcast file |
applicationIcon | System.Drawing.Icon Icon to be displayed in the update UI. If you're invoking this from a form, this would be this.Icon . |
securityMode | NetSparkle.SecurityMode the security mode to be used when checking DSA signatures |
Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon, NetSparkle.SecurityMode securityMode, string dsaPublicKey)
Initializes a new instance of the Sparkle class with the given appcast URL, an Icon for the update UI, the security mode for DSA signatures, and the DSA public key.
Name | Description |
---|---|
appcastUrl | System.String the URL of the appcast file |
applicationIcon | System.Drawing.Icon Icon to be displayed in the update UI. If you're invoking this from a form, this would be this.Icon . |
securityMode | NetSparkle.SecurityMode the security mode to be used when checking DSA signatures |
dsaPublicKey | System.String the DSA public key for checking signatures, in XML Signature ( <DSAKeyValue> ) formatif null, a file named "NetSparkle_DSA.pub" is used instead |
Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon, NetSparkle.SecurityMode securityMode, string dsaPublicKey, string referenceAssembly)
Initializes a new instance of the Sparkle class with the given appcast URL, an Icon for the update UI, the security mode for DSA signatures, the DSA public key, and the name of the assembly to use when comparing update versions.
Name | Description |
---|---|
appcastUrl | System.String the URL of the appcast file |
applicationIcon | System.Drawing.Icon Icon to be displayed in the update UI. If you're invoking this from a form, this would be this.Icon . |
securityMode | NetSparkle.SecurityMode the security mode to be used when checking DSA signatures |
dsaPublicKey | System.String the DSA public key for checking signatures, in XML Signature ( <DSAKeyValue> ) formatif null, a file named "NetSparkle_DSA.pub" is used instead |
referenceAssembly | System.String the name of the assembly to use for comparison when checking update versions |
Sparkle(string appcastUrl, System.Drawing.Icon applicationIcon, NetSparkle.SecurityMode securityMode, string dsaPublicKey, string referenceAssembly, NetSparkle.Interfaces.IUIFactory factory)
Initializes a new instance of the Sparkle class with the given appcast URL, an Icon for the update UI, the security mode for DSA signatures, the DSA public key, the name of the assembly to use when comparing update versions, and a UI factory to use in place of the default UI.
Name | Description |
---|---|
appcastUrl | System.String the URL of the appcast file |
applicationIcon | System.Drawing.Icon Icon to be displayed in the update UI. If you're invoking this from a form, this would be this.Icon . |
securityMode | NetSparkle.SecurityMode the security mode to be used when checking DSA signatures |
dsaPublicKey | System.String the DSA public key for checking signatures, in XML Signature ( <DSAKeyValue> ) formatif null, a file named "NetSparkle_DSA.pub" is used instead |
referenceAssembly | System.String the name of the assembly to use for comparison when checking update versions |
factory | NetSparkle.Interfaces.IUIFactory a UI factory to use in place of the default UI |
Cancels an in-progress download and deletes the temporary file.
Check for updates, using interaction appropriate for if the user just said "check for updates".
Check for updates, using interaction appropriate for where the user doesn't know you're doing it, so be polite.
(WinForms only) Schedules an update check to happen on the first Application.Idle event.
Inherited from IDisposable. Stops all background activities.
Creates a System.Uri from a URL string. If the URL is relative, converts it to an absolute URL based on the appcast URL.
Name | Description |
---|---|
url | System.String relative or absolute URL |
Reads the local Sparkle configuration for the given reference assembly.
This method checks if an update is required. During this process the appcast will be downloaded and checked against the reference assembly. Ensure that the calling process has read access to the reference assembly. This method is also called from the background loops.
Name | Description |
---|---|
config | NetSparkle.Configuration the NetSparkle configuration for the reference assembly |
Returns: NetSparkle.SparkleUpdateInfo with information on whether there is an update available or not.
Used by NetSparkle.AppCast to fetch the appcast and DSA signature.
Used by NetSparkle.AppCast to fetch the appcast and DSA signature as a System.IO.Stream.
Shows the update UI with the latest downloaded update information.
Name | Description |
---|---|
isUpdateAlreadyDownloaded | System.Boolean If true, make sure UI text shows that the user is about to install the file instead of download it. |
Shows the update needed UI with the given set of updates.
Name | Description |
---|---|
updates | NetSparkle.AppCastItem[] updates to show UI for |
isUpdateAlreadyDownloaded | System.Boolean If true, make sure UI text shows that the user is about to install the file instead of download it. |
Starts a NetSparkle background loop to check for updates every 24 hours.
You should only call this function when your app is initialized and shows its main window.
Name | Description |
---|---|
doInitialCheck | System.Boolean whether the first check should happen before or after the first interval |
Starts a NetSparkle background loop to check for updates every 24 hours.
You should only call this function when your app is initialized and shows its main window.
Name | Description |
---|---|
doInitialCheck | System.Boolean whether the first check should happen before or after the first interval |
forceInitialCheck | System.Boolean if doInitialCheck is true, whether the first check should happen even if the last check was less than 24 hours ago |
Starts a NetSparkle background loop to check for updates on a given interval.
You should only call this function when your app is initialized and shows its main window.
Name | Description |
---|---|
doInitialCheck | System.Boolean whether the first check should happen before or after the first period |
forceInitialCheck | System.Boolean if doInitialCheck is true, whether the first check should happen even if the last check was within the last checkFrequency interval |
checkFrequency | System.TimeSpan the interval to wait between update checks |
Starts a NetSparkle background loop to check for updates on a given interval.
You should only call this function when your app is initialized and shows its main window.
Name | Description |
---|---|
doInitialCheck | System.Boolean whether the first check should happen before or after the first interval |
checkFrequency | System.TimeSpan the interval to wait between update checks |
Stops the Sparkle background loop. Called automatically by Dispose.
- string AppcastUrl { get; set; }
- NetSparkle.CheckingForUpdatesWindow CheckingForUpdatesWindow { get; set; }
- System.Action ClearOldInstallers { get; set; }
- NetSparkle.Configuration Configuration { get; set; }
- string CustomInstallerArguments { get; set; }
- NetSparkle.DSAChecker DSAChecker { get; set; }
- NetSparkle.LogWriter LogWriter { get; set; }
- bool EnableSystemProfiling { get; private set; }
- string ExtraJsonData { get; set; }
- bool HideReleaseNotes { get; set; }
- bool HideRemindMeLaterButton { get; set; }
- bool HideSkipButton { get; set; }
- bool IsUpdateLoopRunning { get; }
- NetSparkle.AppCastItem[] LatestAppCastItems { get; }
- PrintDiagnosticToConsole { get; set; }
- NetSparkle.Interfaces.IDownloadProgress ProgressWindow { get; set; }
- bool RelaunchAfterUpdate { get; set; }
- bool ShowsUIOnMainThread { get; set; }
- NetSparkle.Sparkle.SilentModeTypes SilentMode { get; set; }
- System.Uri SystemProfileUrl { get; private set; }
- string TmpDownloadFilePath { get; set; }
- bool TrustEverySSLConnection { get; set; }
- NetSparkle.Interfaces.IUIFactory UIFactory { get; set; }
- bool UpdateMarkedCritical { get; }
- bool UseNotificationToast { get; set; }
- NetSparkle.Interfaces.IUpdateAvailable UserWindow { get; set; }
- NetSparkle.SecurityProtocolType SecurityProtocolType { get; set; }
Gets or sets the appcast URL
The user interface window that shows the 'Checking for Updates...' form. TODO: Make this an interface so user can config their own UI
Function that is called asynchronously to clean up old installers that have been downloaded with SilentModeTypes.DownloadNoInstall or SilentModeTypes.DownloadAndInstall.
The NetSparkle configuration object for the current assembly.
Run the downloaded installer with these arguments
The DSA checker that verifies/validates downloaded files
Logs diagnostic information to Console.WriteLine
or Debug.WriteLine
or wherever else the child class wants to report diagnostic information
Enables system profiling against a profile server. URL to submit to is stored in SystemProfileUrl
If not "", sends extra JSON via POST to server with the web request for update information and for the DSA signature.
Hides the release notes view when an update is found.
Hides the remind me later button when an update is found.
Hides the skip button view when an update is found.
Whether or not the update loop is running
Returns the latest appcast items to the caller. Might be null.
If true, prints diagnostic messages to Console.WriteLine rather than Debug.WriteLine
The user interface window that shows a download progress bar, and then asks to install and relaunch the application
Defines if the application needs to be relaunched after executing the downloaded installer
WinForms only. If true, tries to run UI code on the main thread using System.Threading.SynchronizationContext.
Set the silent mode type for Sparkle to use when there is a valid update for the software
If EnableSystemProfiling is true, system profile information is sent to this URL
If set, downloads files to this path. If the folder doesn't already exist, creates the folder. Note that this variable is a path, not a full file name.
If true, don't check the validity of SSL certificates
Factory for creating UI forms like progress window, etc.
Loops through all of the most recently grabbed app cast items and checks if any of them are marked as critical
Specifies if you want to use the notification toast
The user interface window that shows the release notes and asks the user to skip, later or update
The security protocol (System.Net.SecurityProtocolType
) used by NetSparkle. Setting this property will also set this property for the current AppDomain of the caller. Needs to be set to SecurityProtocolType.Tls12
for some cases, such as downloading something over HTTPS for a GitHub pages site.
- AboutToExitForInstallerRun
- AboutToExitForInstallerRunAsync
- CloseApplication
- CloseApplicationAsync
- CheckLoopFinished
- CheckLoopStarted
- DownloadCanceled
- DownloadedFileIsCorrupt
- DownloadedFileReady
- DownloadError
- FinishedDownloading
- StartedDownloading
- UpdateCheckFinished
- UpdateCheckStarted
- UpdateDetected
- UserSkippedVersion
- RemindMeLaterSelected
Delegate: void System.ComponentModel.CancelEventHandler(object sender, System.ComponentModel.CancelEventArgs e)
Subscribe to this to get a chance to shut down gracefully before quitting. If AboutToExitForInstallerRunAsync is set, this has no effect.
Delegate: Task CancelEventHandlerAsync(object sender, System.ComponentModel.CancelEventArgs e)
Subscribe to this to get a chance to asynchronously shut down gracefully before quitting. This overrides AboutToExitForInstallerRun.
Delegate: void CloseApplication()
Event for custom shutdown logic. If this is set, it is called instead of Application.Current.Shutdown or Application.Exit. If CloseApplicationAsync is set, this has no effect.
Warning: The batch file that launches your executable only waits for 90 seconds before giving up! Make sure that your software closes within 90 seconds if you implement this event! If you need an event that can be canceled, use AboutToExitForInstallerRun.
Delegate: Task CloseApplicationAsync()
Event for custom shutdown logic. If this is set, it is called instead of Application.Current.Shutdown or Application.Exit. This overrides CloseApplication.
Warning: The batch file that launches your executable only waits for 90 seconds before giving up! Make sure that your software closes within 90 seconds if you implement this event! If you need an event that can be canceled, use AboutToExitForInstallerRunAsync.
Delegate: void NetSparkle.LoopFinishedOperation(object sender, bool updateRequired)
This event will be raised when a check loop is finished
Delegate: void NetSparkle.LoopStartedOperation(object sender)
This event will be raised when a check loop will be started
Delegate: void NetSparkle.DownloadEvent(string path)
Called when the download has been canceled
Delegate: void NetSparkle.DownloadedFileIsCorrupt(NetSparkle.AppCastItem item, string downloadPath)
Called when the downloaded file is downloaded (or at least partially on disk) and the DSA signature doesn't match. When this is called, Sparkle is not taking any further action to try to download the install file during this instance of the software. In order to make Sparkle try again, you must delete the file off disk yourself. Sparkle will try again after the software is restarted.
Delegate: void NetSparkle.DownloadedFileReady(NetSparkle.AppCastItem item, string downloadPath)
Called when the downloaded file is fully downloaded and verified regardless of the value for SilentMode. Note that if you are installing fully silently, this will be called before the install file is executed, so don't manually initiate the file or anything.
Delegate: void NetSparkle.DownloadEvent(string path)
Called when the download has downloaded but has an error other than corruption
Delegate: void NetSparkle.DownloadEvent(string path)
Called when the download has finished successfully
Delegate: void NetSparkle.DownloadEvent(string path)
Called when the download has just started
Delegate: void NetSparkle.UpdateCheckFinished(object sender, NetSparkle.UpdateStatus status)
Called when update check is all done. May or may not have called UpdateDetected in the middle.
Delegate: void NetSparkle.UpdateCheckStarted(object sender)
Called when update check has just started
Delegate: void NetSparkle.UpdateDetected(object sender, NetSparkle.UpdateDetectedEventArgs e)
This event can be used to override the standard user interface process when an update is detected
Delegate: void NetSparkle.UserSkippedVersion(NetSparkle.AppCastItem item, string downloadPath)
Called when the user skips some version of the application.
Delegate: void NetSparkle.RemindMeLaterSelected(AppCastItem item);
Called when the user skips some version of the application by clicking the 'Remind Me Later' button
NetSparkle is available under the MIT License.
- .NET 4.5
An incomplete list of other projects related to software updating: