
Un framework de mise à jour logiciel facilement personnalisable pour les projets C # .NET avec des UIS intégrés pour WinForms, WPF et Avalonia
NetSparkle est un framework de mise à jour logiciel hautement configurable pour C # qui est compatible avec .NET 6+ et .NET Framework 4.6.2+, possède des UIS pré-construites pour .NET Framework (WinForms, WPF) et .NET 6+ (WinForms, WPF, Avalonia), utilise ED25519 ou d'autres signatures cryptantes, et permet même des UI personnalisé Vous fournissez, quelque part sur Internet, une application coulée avec des informations de mise à jour et de version, ainsi que des notes de publication au format Markdown ou HTML. Cette bibliothèque vous aide ensuite à vérifier une mise à jour, à afficher à l'utilisateur les notes de publication et à offrir pour télécharger / installer la nouvelle version du logiciel.
Types de téléchargement de mise à jour pris en charge intégrés:
Veuillez consulter la mise à niveau.md pour plus d'informations sur les modifications de version majeure, les mises à jour, etc.
NetSparkle est disponible via Nuget. Pour choisir un package NuGet à utiliser:
NetSparkleUpdater.SparkleUpdater package de base si vous ne vous souciez pas d'avoir une interface utilisateur intégrée et que vous pouvez gérer les choses vous-même| Emballer | Cas d'utilisation | Libérer | Prévisualisation | Téléchargements |
|---|---|---|---|---|
| Netsparkleupdater.sparkleupdater | Package de base; Utilisez une interface utilisateur 100% personnalisée ou pas d'interface utilisateur (rien de intégré) | |||
| WinForms UI (.NET Framework) | NetSparkle avec ui WinForms intégré | |||
| Winforms ui (.net 6+) | NetSparkle avec ui WinForms intégré | |||
| WPF UI (.net framework et .net 6+) | NetSparkle avec UI WPF intégré | |||
| Avalonia ui | NetSparkle avec UI Avalonia intégré | |||
| Outil de générateur de fonds d'application | netsparkle-generate-appcast CLI Tool (incl. ED25519 Aiders) | |||
| Outil d'assistance DSA | Outil CLI netsparkle-dsa (Aiders DSA) |
Informations rapides pour les installations d'outils:
dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator ; Disponible en tant que netsparkle-generate-appcast sur votre ligne de commande après l'installationdotnet tool install --global NetSparkleUpdater.Tools.DSAHelper ; Disponible en tant que netsparkle-dsa sur votre ligne de commande après l'installation Un chemin de mise à jour logiciel typique pour un logiciel stéréotypé peut ressembler à ceci:
dotnet publish )En ce moment, NetSparkleupDater ne vous aide pas avec 1., 2., ou 4. "Pourquoi pas?", Vous pourriez demander:
sudo pour une raison quelconque, il y a un exemple de le faire dans l'échantillon de MacOS Avalonia .Pour créer votre fichier de distribution d'application, consultez la section CAST de l'application de ce document.
Nous sommes ouverts aux contributions qui pourraient faciliter le processus d'installation / mise à jour global pour l'utilisateur. Veuillez déposer un problème d'abord avec votre idée avant de commencer le travail afin que nous puissions en parler.
Veuillez consulter les exemples de projets dans ce référentiel pour des échantillons d'utilisation de base et coulissables !! Il existe des échantillons sur l'utilisation de chacune des interfaces utilisateur intégrées ainsi qu'un échantillon "Faites-le vous-même dans votre propre interface utilisateur"!
dotnet tool install --global NetSparkleUpdater.Tools.AppCastGeneratornetsparkle-generate-appcast --generate-keys
# By default, your Ed25519 signatures are stored on disk in your local
# application data folder in a subdirectory called `netsparkle`.
# If you want to export your keys to the console, you can do:
netsparkle-generate-appcast --exportMainWindow ou principal ou similaire: private SparkleUpdater _sparkle ;
// on your main thread...
_sparkle = new SparkleUpdater (
"https://mywebsite.com/appcast.xml" , // link to your app cast file - change extension to .json if using json
new Ed25519Checker ( SecurityMode . Strict , // security mode -- use .Unsafe to ignore all signature checking (NOT recommended!!)
"base_64_public_key_from_generate_app_cast_tool" ) // your base 64 public key
) {
UIFactory = new NetSparkleUpdater . UI . WPF . UIFactory ( icon ) , // or null, or choose some other UI factory, or build your own IUIFactory implementation!
RelaunchAfterUpdate = false , // set to true if needed
} ;
_sparkle . StartLoop ( true ) ; // will auto-check for updatesInnoSetup (Windows), un fichier DMG (Linux), un fichier .tar.gz (Linux) ou similaire. Plus d'informations dans la section des mises à jour comment fonctionnent.netsparkle-generate-appcast --help pour les options): netsparkle-generate-appcast -b binary/folder -p change/log/folder -u https://example.com/downloads -l https://example.com/downloads/changelogs.signature ou fichiers similaires) aux emplacements appropriés de votre serveurSparkleUpdater.LogWriter pour voir s'il existe des informations de débogage utiles apparaissant sur la console! Dans votre fichier de projet, assurez-vous de configurer quelques éléments afin que la bibliothèque puisse lire dans les détails pertinents plus tard. Remarque: Vous pouvez utiliser votre propre IAssemblyAccessor pour charger des informations de version ailleurs. Cependant, la configuration des choses dans votre fichier de projet est facile, et NetSparkleupDater peut le lire en nativement!
< PropertyGroup >
< Version >1.0.2-beta1</ Version > <!-- accepts semver -->
< AssemblyVersion >1.0.2</ AssemblyVersion > <!-- only accepts Major.Minor.Patch.Revision -->
< AssemblyTitle >My Best App</ AssemblyTitle >
<!-- When using AssemblyDiagnosticsAccessor, accessor.AssemblyTitle is actually the
<Product> information due to limitations with the way the diagnostics access works -->
< Description >My app is cool (not required)</ Description >
< Company >My Company Name (required unless you set the IAssemblyAccessor save path yourself)</ Company >
< Product >My Product (required unless you set the IAssemblyAccessor save path yourself; set to product name e.g. MyBestApp)</ Product >
< Copyright >2024 MyCompanyName</ Copyright >
</ PropertyGroup > Remarque importante: Dans .NET 8+, un changement a été apporté dans le cœur de .NET qui fait que votre hachage Git / Source Code Commit est inclus dans le numéro <Version> de votre application. Ce comportement ne peut pas être évité par NetSparkleupDater pour le moment car nous nous appuyons sur AssemblyInformationalVersionAttribute , et le comportement de cet attribut a été modifié. Vos utilisateurs peuvent être informés qu'ils exécutent actuellement 1.0.0+commitHashHere par NetSparkleupDater (et votre application native elle-même!). Nous vous recommandons également d'ajouter les lignes suivantes à votre fichier de projet (dans un nouveau <PropertyGroup> ou un nouveau existant):
< IncludeSourceRevisionInInformationalVersion >false</ IncludeSourceRevisionInInformationalVersion > // NOTE: Under most, if not all, circumstances, SparkleUpdater should be initialized on your app's main UI thread.
// This way, if you're using a built-in UI with no custom adjustments, all calls to UI objects will automatically go to the UI thread for you.
// Basically, SparkleUpdater's background loop will make calls to the thread that the SparkleUpdater was created on via SyncronizationContext.
// So, if you start SparkleUpdater on the UI thread, the background loop events will auto-call to the UI thread for you.
_sparkle = new SparkleUpdater (
"http://example.com/appcast.xml" , // link to your app cast file
new Ed25519Checker ( SecurityMode . Strict , // security mode -- use .Unsafe to ignore all signature checking (NOT recommended!!)
"base_64_public_key" ) // your base 64 public key -- generate this with the NetSparkleUpdater.Tools.AppCastGenerator .NET CLI tool on any OS
) {
UIFactory = new NetSparkleUpdater . UI . WPF . UIFactory ( icon ) , // or null, or choose some other UI factory, or build your own IUIFactory implementation!
RelaunchAfterUpdate = false , // default is false; set to true if you want your app to restart after updating (keep as false if your installer will start your app for you)
CustomInstallerArguments = "" , // set if you want your installer to get some command-line args
} ;
_sparkle . StartLoop ( true ) ; // `true` to run an initial check online -- only call StartLoop **once** for a given SparkleUpdater instance!Sur l'événement d'application Application.idle, votre fichier XML accéléré sera téléchargé, lu et comparé à la version en cours d'exécution. S'il a une mise à jour logicielle à l'intérieur, l'utilisateur sera informé avec une petite notification de toast (si elle est prise en charge par l'interface utilisateur et activée) ou avec une boîte de dialogue de mise à jour contenant vos notes de publication. L'utilisateur peut ensuite ignorer la mise à jour, demander à être rappelé plus tard ou le télécharger / l'installer maintenant.
Si vous souhaitez vérifier une mise à jour en arrière-plan sans que l'utilisateur ne voit rien, utilisez
var updateInfo = _sparkle . CheckForUpdatesQuietly ( ) ;Si vous souhaitez avoir un élément de menu pour que l'utilisateur vérifie les mises à jour afin que l'utilisateur puisse voir l'interface utilisateur tandis que NetSparkle recherche des mises à jour, utilisez
_sparkle . CheckForUpdatesAtUserRequest ( ) ;Si vous avez des fichiers qui doivent être enregistrés, abonnez-vous à l'événement de préparation à l'heure:
_sparkle . PreparingToExit += ( ( x , cancellable ) =>
{
// ask the user to save, whatever else is needed to close down gracefully
} ) ; Notez que si vous n'utilisez pas de UIFactory , vous devez utiliser les événements CloseApplication ou CloseApplicationAsync pour fermer votre application; Sinon, votre fichier de mise à jour téléchargé ne sera jamais exécuté / lu! La seule exception à cela est si vous souhaitez gérer tous les aspects de l'installation du package de mise à jour vous-même.
Le fichier qui lance votre mise à jour téléchargé Executable n'attend que 90 secondes avant d'abandonner! Assurez-vous que votre logiciel se ferme dans les 90 secondes suivant le suivi de CloseApplication / CloseApplicationAsync si vous implémentez ces événements! Si vous avez besoin d'un événement qui peut être annulé, par exemple lorsque l'utilisateur doit être demandé s'il est acceptable de fermer (par exemple pour enregistrer son travail), utilisez PreparingForExit ou PreparingToExitAsync .
IUIFactory ; Définissez SparkleUpdater.UIFactory pour utiliser une instance de votre objet.ICheckingForUpdates pour votre interface utilisateur qui indique à l'utilisateur que SparkleUpdater vérifie les mises à jourIDownloadProgress pour votre interface utilisateur qui montre à l'utilisateur qu'une mise à jour est en cours de téléchargementIUpdateAvailable pour votre interface utilisateur qui montre à l'utilisateur qu'une mise à jour est disponible avec les notes de publicationIAppCastDataDownloader pour configurer vos propres méthodes pour télécharger des données de distribution d'applications; Définissez SparkleUpdater.AppCastDataDownloader pour utiliser une instance de votre objet. NetSparkle inclut deux implémentations par défaut: WebRequestAppCastDataDownloader pour télécharger des informations sur les applications sur Internet en grande partie, et LocalFileAppCastDownloader pour copier / "télécharger" une application coulée à partir d'un chemin donné, localFileAppcastDown.IAppCastFilter pour effectuer un filtrage personnalisé sur les objets AppCastItem dans votre casting d'application téléchargé, par exemple pour considérer un sous-ensemble donné d'éléments comme des mises à jour valides pour votre application; Définissez AppCastHelper.AppCastFilter ( SparkleUpdater.AppCastHelper.AppCastFilter ) pour utiliser une instance de votre objet. NetSparkle comprend la classe ChannelAppCastFilter , que vous pouvez utiliser pour filtrer les éléments par un canal produit donné (par exemple alpha, bêta) si votre application utilise ces fonctionnalités.IAppCastGenerator pour contrôler comment les acteurs d'applications sont sérialisés et désérialisés; Définissez SparkleUpdater.AppCastGenerator pour utiliser une instance de votre objet. NetSparkle comprend deux implémentations: XMLAppCastGenerator , pour la sérialisation / désérialisation XML; et JsonAppCastGenerator , pour la sérialisation / désérialisation JSON. L'outil CLI du générateur de plâtre de l'application peut également sortir à la fois des moulages de l'application XML et JSON.IAssemblyAccessor pour contrôler comment la version, le droit d'auteur et d'autres détails du produit sont chargés pour votre application; Définissez Configuration.AssemblyAccessor ( SparkleUpdater.Configuration.AssemblyAccessor ) pour utiliser une instance de votre objet. NetSparkle contient une implémentation par défaut, AssemblyDiagnosticsAccessor , qui devrait fonctionner dans le cas général du chargement des données à partir d'un assemblage donné.ILogger et définissez SparkleUpdater.LogWriter . Par défaut, la classe LogWriter est utilisée (qui a la propriété LogWriterOutputMode pour contrôler si les journaux sont écrits sur Console , Trace , etc.)ISignatureVerifier pour modifier la façon dont vos signatures pour la distribution de l'application, les téléchargements, etc. sont gérées; Définissez SparkleUpdater.SignatureVerifier pour utiliser une instance de votre objet.IUpdateDownloader pour configurer vos propres méthodes pour télécharger et envoyer des progrès sur les fichiers de mise à jour des applications (par exemple, les installateurs) pour un élément de distribution d'application donné; Définissez SparkleUpdater.UpdateDownloader pour utiliser une instance de votre objet. NetSparkle inclut deux implémentations par défaut: WebFileDownloader (par défaut) pour télécharger des fichiers à partir du Web / Internet, et LocalFileDownloader pour copier / "télécharger" un fichier à partir d'un chemin donné. Configuration de la sous-classe pour modifier la façon dont certaines informations NetSparkle sont enregistrées et chargées - par exemple, les informations de version sautés. Cette classe est celle qui utilise une instance IAssemblyAccessor pour enregistrer et charger les informations de version, le nom du produit, etc. NetSparkle contient trois implémentations: RegistryConfiguration , qui enregistre et charge les informations du registre Windows (par défaut sur Windows); JSONConfiguration , qui enregistre et charge les informations sur un fichier JSON (par défaut sur macOS / Linux); et DefaultConfiguration , qui ne fait rien et sert de repli au cas où JSONConfiguration ne peut pas trouver un emplacement de fichier valide pour enregistrer et charger des données. Pour utiliser l'instance de votre classe, définissez SparkleUpdater.Configuration .RegistryConfiguration vous permet de modifier rapidement le chemin du registre où les éléments sont enregistrés via BuildRegistryPathJSONConfiguration vous permet de modifier rapidement le chemin du fichier où les données sont enregistrées via GetSavePathAppCastHelper Si vous souhaitez un contrôle complet sur le processus de téléchargement et d'analyse de la distribution de l'application. Notez que vous pouvez probablement faire tout ce que vous devez faire via les propriétés AppCastHelper (y compris IAppCastFilter AppCastFilter ), mais la sous-classe vous donnera un contrôle absolu complet sur tout le processus. Pour utiliser l'instance de votre classe, définissez SparkleUpdater.AppCastHelper .ReleaseNotesGrabber pour contrôler le processus de téléchargement (et donc d'affichage) des notes de version. Pour utiliser une instance de votre classe, définissez UIFactory.ReleaseNotesGrabberOverride .WebFileDownloader si vous ne souhaitez pas implémenter IUpdateDownloader vous-même et que vous souhaitez simplement remplacer une fonction ou deux telles que CreateHttpClient ou RetreiveDestinationFileNameAsync . Pour utiliser une instance de votre classe, définissez SparkleUpdater.UpdateDownloader .WebRequestAppCastDataDownloader si vous ne souhaitez pas implémenter IAppCastDataDownloader et que vous souhaitez simplement remplacer une fonction ou deux telles que CreateHttpClient . Pour utiliser une instance de votre classe, définissez SparkleUpdater.AppCastDataDownloader .LogWriter pour implémenter la fonction PrintMessage ; Parce ILogger est une interface assez simple, vous pouvez probablement simplement implémenter cette interface si vos besoins sont complexes. Pour utiliser une instance de votre classe, définissez SparkleUpdater.LogWriter .SparkleUpdater pour implémenter différentes fonctions liées à l'installation, notamment:GetWindowsInstallerCommandGetInstallerCommandRunDownloadedInstallerGetDownloadPathForAppCastItemUIFactory si vous ne souhaitez pas implémenter vous-même l'interface IUIFactory et que vous souhaitez simplement configurer une fonction ou deux. Pour utiliser une instance de votre classe, définissez SparkleUpdater.UIFactory . IAppCastFilter Vous pouvez modifier la façon dont vos éléments de distribution d'applications sont filtrés via la propriété AppCastHelper.AppCastFilter (via l'interface IAppCastFilter ). Cela vous permet de modifier les éléments mis à la disposition de vos utilisateurs finaux.
NetSparkle contient une implémentation IAppCastFilter intégrée pour le filtrage basé sur les canaux appelé ChannelAppCastFilter . Pour quelques exemples sur la façon d'utiliser cette classe, consultez les tests unitaires ici. Fondamentalement, définissez la propriété List<string> ChannelSearchNames sur les canaux que vous souhaitez filtrer. Si vous souhaitez conserver des éléments sans info de canal (par exemple 1.2.3 ), définissez KeepItemsWithNoChannelInfo sur true .
Pour définir réellement les canaux sur votre application, les éléments de votre application / dans votre application CAST, utilisez la propriété --channel de l'outil CLI CAST APP ou définissez la propriété <Version> de votre fichier de projet dans la version compatible SEMVER applicable (par exemple, l'outil CLI <Version>1.0.2-beta1</Version> ), et l'application CONST CLI Tool le ramassera automatiquement. Ou, si vous construisez votre application CAST manuellement, définissez la propriété <sparkle:channel>YourChannelHere</sparkle:channel> sur votre <item> (ou, si vous utilisez JSON, la propriété channel ).
NetSparkleupDater n'a pas à être utilisé avec une interface utilisateur. Vous pouvez tout faire vous-même ou même que la bibliothèque exécute votre mise à jour téléchargée automatiquement en définissant le SparkleUpdater.UserInteractionMode = UserInteractionMode.DownloadAndInstall . Ce dépôt a un échantillon pour faire les choses vous-même sans aucune interface utilisateur prédéfinie dans SRC / NETSPARKLE.Samples.Handleeventsy vous-même.
Si vous voulez une interface utilisateur, nous proposons des UIS pré-construites dans différents packages NuGet avec un petit nombre d'options personnalisables pour WinForms, WPF et Avalonia. Les UIS sont déclenchées via une implémentation IUIFactory , appelée UIFactory dans chacune des options intégrées. La plupart des méthodes de l' UIFactory peuvent être remplacées si vous souhaitez modifier le comportement, et le ProcessWindowAfterInit vous permet de personnaliser chaque fenêtre après sa réalisation.
Si vous souhaitez enlever votre propre UI entièrement, implémentez simplement l'interface IUIFactory avec la bibliothèque d'interface utilisateur que vous souhaitez utiliser. Vous pouvez copier ou réutiliser des modèles de vue, du code, etc. à partir des options pré-construites de NetSparkleupDater, et copier + coller du code de ce référentiel dans le vôtre est probablement un bon moyen rapide de commencer. N'oubliez pas de définir la propriété SparkleUpdater.UIFactory avec une instance de votre implémentation IUIFactory , cependant!
Veuillez noter: NetSparkle ne tente essentiellement pas de s'inquiéter du filetage (par exemple, appelez le thread principal), à l'exception de la boucle d'arrière-plan appelant le fil principal qui a commencé l'instance SparkleUpdater . En d'autres termes, de manière générale, NetSparkle fera tout sur le fil qui a créé à l'origine l'instance SparkleUpdater . Pour la plupart des applications, ce sera bien car ils utilisent simplement leur fil d'interface utilisateur principal. En cas de doute, pour vos propres besoins d'interface utilisateur, assurez-vous de vérifier InvokeRequired sur WinForms, et sur WPF / Avalonia, les choses maréchalaient sur le thread d'interface utilisateur (sauf si vous utilisez la liaison des données dans ce cas qu'elle est traitée pour vous!).
Passer votre propre implémentation IUIFactory qui démarre Windows / Things sur de nouveaux threads dans SparkleUpdater n'est pas une configuration prise en charge. Si vous souhaitez exécuter votre propre interface utilisateur sur plusieurs threads (par exemple pour que WinForms ne disposait pas des fenêtres de NetSparkleupDater à la fermeture du formulaire principal), faites-le en utilisant les événements de SparkleUpdater et non de l' UIFactory ; Veuillez également consulter l'échantillon SRC / NetSparkle.Samples.Forms.Multithread pour un exemple pratique de la façon de le faire.
Le casting de l'application n'est qu'un fichier XML ou JSON. Il contient des champs tels que le titre et la description de votre produit ainsi qu'une définition par version de votre logiciel.
Nous vous recommandons fortement d'utiliser l'outil NetSparkle-Generate-Appcast pour créer (et plus tard, recréer / mettre à jour) le fichier car il peut vous aider à prendre en charge toutes les exigences de signature pour vous.
dotnet tool install --global NetSparkleUpdater.Tools.AppCastGeneratornetsparkle-generate-appcast . Vous pouvez utiliser netsparkle-generate-appcast --help pour voir une liste complète d'options pour cet outil. Par défaut, NetSparkle utilise pour la plupart des fonds d'application XML compatibles Sparkle. NetSparkle utilise sparkle:signature plutôt que sparkle:edSignature afin que vous puissiez choisir comment signer vos fichiers / actuation. (Si vous souhaitez utiliser sparkle:edSignature , pass --use-ed25519-signature-attribute au générateur de distribution de l'App.) Notez que NetSparkle est compatible avec et utilise les signatures ED25519 par défaut, mais le cadre peut gérer une implémentation différente de la classe ISignatureVerifier pour vérifier différents types de signatures sans une version majeure / mise à jour / mise à jour.
Voici un exemple de distribution d'application XML:
<? 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 > NetSparkle lit les balises <item> pour déterminer si les mises à jour sont disponibles.
Les balises importantes de chaque <item> sont:
<description><sparkle:releaseNotesLink> .<sparkle:releaseNotesLink><description> est présente, elle sera utilisée à la place.sparkle:signature , facultatif: la signature DSA / ED25519 du document; NetSparkle ne vérifie pas cette signature à moins que vous ne définissiez ReleaseNotesGrabber.ChecksReleaseNotesSignature sur true , mais vous pouvez vérifier manuellement les signatures de changelog si vous aimez ou définissez ReleaseNotesGrabber.ChecksReleaseNotesSignature = true dans votre ui.<pubDate>sparkle:channel : canal pour cet élément de distribution d'application, par exemple beta (non requis) - accepte seulement 1 canal<enclosure>url : URL du fichier de mise à joursparkle:version : Numéro de version lisible par machine de cette mise à jourlength , facultatif: (non validé) Taille du fichier de mise à jour en octetstype : ignorésparkle:signature : DSA / ED25519 Signature du fichier de mise à joursparkle:criticalUpdate , facultatif: s'il est égal à true ou 1 , l'interface utilisateur indique qu'il s'agit d'une mise à jour critiquesparkle:os : Système d'exploitation pour l'élément de distribution de l'application. Par défaut sous Windows s'il n'est pas fourni. Pour Windows, utilisez "Win" ou "Windows"; Pour MacOS, utilisez "macOS" ou "OSX"; Pour Linux, utilisez "Linux". Par défaut, vous avez besoin de 2 signatures ( SecurityMode.Strict ):
sparkle:signature="..." )Remarque: L'outil Générateur CAST APP crée ces deux signatures pour vous lorsqu'il recrée le fichier appcast.xml.
Vous pouvez générer des signatures ED25519 à l'aide de l'outil AppCastGenerator (à partir de ce package NuGet ou dans le code source ici). Cet outil nécessite l'installation de l'installation de l'installation de fonctionnement .net 6, 7, 8 ou 9. Veuillez consulter des sections ci-dessous pour les options et des exemples sur la génération des clés ED25519 et pour les utiliser lors de la création d'un casting d'application.
AppCastGenerator (à partir de ce package NuGet ou dans le code source ici) pour créer facilement votre fichier de distribution d'application. Les options disponibles sont décrites ci-dessous. Vous pouvez l'installer sur votre CLI via dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator .string.Format ou similaire est une chose merveilleuse).Si vous souhaitez utiliser un casting d'application JSON plutôt que XML:
--output-type json lors de la génération de votre fichier de distribution d'application via le générateur de casting de l'applicationSparkleUpdater.AppCastGenerator à new JsonAppCastGenerator(mySparkleUpdater.LogWriter) .JsonAppCastGenerator.HumanReadableOutput sur false .Vous manquez une option que vous aimeriez voir? Déposez un problème sur ce dépôt ou ajoutez-le vous-même et envoyez-nous une demande de traction!
--show-examples : Imprimez des exemples d'utilisation de la console.--help : Affichez toutes les options et leurs descriptions. -a / --appcast-output-directory : répertoire dans lequel écrire le fichier de sortie appcast.xml . Exemple d'utilisation: -a ./MyAppCastOutput-e / --ext : Lorsque vous recherchez des fichiers à ajouter à l'application, utilisez les extensions données lorsque vous recherchez des fichiers. Par défaut est exe . Exemple d'utilisation: -e exe,msi-b / --binaries : chemin de fichier vers le répertoire qui doit être recherché lors de la recherche de fichiers à ajouter à la distribution de l'application. Par défaut . . Exemple d'utilisation: -b my/build/directory-r / --search-binary-subdirectories : fidèle à rechercher le répertoire binaire récursivement des binaires; Faux pour rechercher uniquement le répertoire supérieur. Par défaut est false . Exemple d'utilisation: -r .--single-file : un seul fichier à ajouter à l'application Cast - Si défini, --binaries , --ext , etc. sont tous ignorés. Utile à utiliser si votre fichier de sortie n'a pas d'extension (par exemple, un exécutable UNIX). Exemple Utilisation: --single-file path/to/my/file-f / --file-extract-version : s'il faut extraire la version du fichier du nom du fichier plutôt que le fichier (par exemple DLL) lui-même. Par défaut est false . Utilisez lorsque vos fichiers qui seront téléchargés par NetSparkleupDater auront le numéro de version dans le nom du fichier, par exemple "mon application 1.3.2-alpha1.exe". Notez que cela ne recherche que les quatre derniers éléments / dossiers du répertoire. Exemple d'utilisation: -f true--file-version : utilisez pour définir la version pour un binaire dans un casting d'application. Notez que cette version ne peut être définie qu'une seule fois, donc lors de la génération d'un casting d'application, assurez-vous que vous: a) n'ont qu'un seul binaire dans votre application CAST | B) Utilisez le paramètre --reparse-existing pour que les anciens articles soient ramassés. Si le générateur trouve 2 binaires sans aucune version connue et --file-version est définie, une erreur sera émise. Exemple Utilisation: --file-version 1.3.2-o / --os : Système d'exploitation auquel appartiennent les éléments de la distribution de l'application. La chaîne doit inclure l'un des éléments suivants: windows , mac , linux . Par défaut vers windows . Exemple d'utilisation: -o macos-arm64 ; -o windows-x64--description-tag : texte à mettre dans l'application Cast Description Tag / Informations. Par défaut, "Modifications les plus récentes avec les liens vers les mises à jour". Exemple Utilisation: --description-tag "Hello I am a Cool App"--link-tag : texte à mettre dans l'application CAST link TAG / INFORMATION. Devrait être votre application de téléchargement de téléchargement si vous l'utilisez. Exemple Utilisation: --link-tag https://mysite.com/coolapp/appcast.xml-u / --base-url : Portion de départ de l'URL à utiliser pour les téléchargements. Le nom de fichier qui sera téléchargé sera mis en place après cette partie de l'URL. Exemple Utilisation: -u https://myawesomecompany.com/downloads-l / --change-log-url : partie de départ de l'URL à utiliser pour vos fichiers journaux de modification. Le fichier journal de modification qui sera téléchargé sera mis en place après cette partie de l'URL. Si cette option n'est pas spécifiée, les données de journal de modification seront placées dans l'application Cast lui-même. Exemple d'utilisation: -l https://myawesomecompany.com/changes-p / --change-log-path : chemin vers les fichiers journaux de modification de votre logiciel. Ceux-ci devraient être au format Markdown avec une extension de .md . Le nom de fichier des fichiers journaux de modification doit contenir la version du logiciel, par exemple 1.3.2.md Exemple Utilisation: -p path/to/change/logs . (Remarque: le générateur tentera également de trouver des journaux de modification dont les noms de fichiers sont formatés comme: MyApp 1.3.2.md )--change-log-name-prefix : préfixe pour modifier les noms de fichiers journaux. Par défaut, le générateur recherche des noms de fichiers avec le format "[version] .md". Si vous définissez ce paramètre sur (par exemple) "mon journal de modification de l'application", il recherchera les noms de fichiers avec le format "My App Change Log [version] .md" ainsi que "[version] .md".-n / --product-name : Nom du produit pour votre logiciel. Utilisé lors de la définition du titre pour votre application CAST et ses articles. Par défaut à Application . Exemple d'utilisation: -n "My Awesome App"-x / --url-prefix-version : Ajoutez le numéro de version en tant que préfixe au nom du fichier pour l'URL de téléchargement. Par défaut est faux. Par exemple, si --base-url est www.example.com/downloads , votre version est 1.4.2 et le nom de votre application est MyApp.exe , votre URL de téléchargement deviendra www.example.com/downloads/1.4.2/MyApp.exe . Exemple d'utilisation: -x true .--key-path : chemin vers NetSparkle_Ed25519.priv et NetSparkle_Ed25519.pub , qui sont respectivement vos clés privées et publiques ED25519 pour vos mises à jour logicielles. Exemple Utilisation: --key-path my/path/to/keysSPARKLE_PRIVATE_KEY et SPARKLE_PUBLIC_KEY avant d'exécuter generate_appcast . L'outil priorise les clés de l'environnement sur les clés assises sur le disque!--signature-file-extension : Extension (sans le . ) À utiliser pour le fichier de signature de la fonte de l'application. signature par défaut. Exemple Utilisation: --signature-file-extension txt .--output-file-name : Nom du fichier de sortie pour l'application CAST avec le . ou l'extension. L'extension est contrôlée par le fait qu'il s'agisse d'une sortie XML ou JSON et n'est pas configurable. Par défaut «Appcast». Bien sûr, vous pouvez toujours changer cela plus tard par vous-même après la génération de la distribution de l'application; Cette option est uniquement pour la commodité. Exemple d'utilisation: --output-file-name super_app_download_info .--use-ed25519-signature-attribute : Si TRUE et FAIT SORTIE XML, l'attribut de signature de sortie dans le XML sera edSignature plutôt que signature pour correspondre à la bibliothèque Sparkle d'origine. Aucun effet sur les lancers de l'application JSON.--file-version : utilisez pour définir la version pour un binaire dans un casting d'application. Notez que cette version ne peut être définie qu'une seule fois, donc lors de la génération d'un casting d'application, assurez-vous que vous: a) n'ont qu'un seul binaire dans votre application CAST | B) Utilisez le paramètre --reparse-existing pour que les anciens articles soient ramassés. Si le générateur trouve 2 binaires sans aucune version connue et --file-version est définie, une erreur sera émise.--critical-versions : liste de versions séparées par des virgules à considérer comme critique dans le casting de l'application. Doit correspondre exactement au texte de la version. Par exemple, "1.0.2,1.2.3.1".--reparse-existing : re-parse une application existante coulée plutôt que de la remplacer et de la créer à nouveau. Skips Versions déjà dans le casting de l'application, donc si vous déployez un nouveau binaire avec la même version, vous devrez modifier manuellement votre distribution d'application pour supprimer l'ancienne liste de la version que vous redémarrez. EXEMPLE UTILISATION: --reparse-existing true--overwrite-old-items : fait réécrire les éléments de la distribution de l'application dans la distribution de l'application si le binaire sur disque avec le même numéro de version est trouvé. En d'autres termes, si 1.0.1 se trouve déjà dans l'application (soit à partir de la répartition ou d'un autre binaire), et un autre 1.0.1 se trouve sur le disque, les données 1.0.1 dans le casting de l'application seront réécrites en fonction du binaire trouvé. Notez que cela signifie que si vous avez plusieurs versions 1.0.1 sur disque (ce que vous ne devriez pas faire ...), la dernière sera celle de votre application! Exemple d'utilisation: --overwrite-old-items--human-readable : Si vrai, rend le fichier de sortie de sortie de sortie humain lisible (lignes de nouvelles, indents). Exemple Utilisation: --human-readable true--channel : nom du canal de version pour tous les éléments ajoutés dans le casting de l'application. Devrait être un seul canal; does not support multiple channels at once, eg beta,gamma . Do not set if you want to use your release channel - if you set this to release or stable , those names/words will be treated as special channels and not as the stable channel. (Unless you want all your items to be in a specific channel, of course.) Example use: --channel beta--output-type : Output type for the app cast file ( xml or json ). Defaults to xml . Example use: --output-type json --public-key-override : Public key override (ignores whatever is in the public key file) for signing binaries. This overrides ALL other public keys set when verifying binaries, INCLUDING public key set via environment variables! If not set, uses --key-path (if set) or the default SignatureManager location. Not used in --generate-keys or --export . Example use: --public-key-override asoj341ljsdflj--private-key-override : Private key override (ignores whatever is in the private key file) for signing binaries. This overrides ALL other public keys set when verifying binaries, INCLUDING private key set via environment variables! If not set, uses --key-path (if set) or the default SignatureManager location. Not used in --generate-keys or --export . Example use: --private-key-override asoj341ljsdflj --generate-keys : If set, will attempt to generate NEW Ed25519 keys for you. Can be used in conjunction with --key-path . Once keys are successfully (or unsuccessfully) generated, the program ends without generating an app cast. By default, existing keys are not overwritten. This option defaults to false .--force : If set to true , will overwrite existing keys on disk. WARNING: THIS COULD RESULT IN A LOSS OF YOUR PUBLIC AND PRIVATE KEYS. USE WITH CAUTION. DO NOT USE IF YOU DO NOT KNOW WHAT YOU ARE DOING! THIS WILL MAKE NO ATTEMPT TO BACK UP YOUR DATA. This option defaults to false . Example use: --generate-keys --force true .--export : Export keys as base 64 strings to the console. Defaults to false . Example use: --export true . Output format: Private Key:
2o34usledjfs0
Public Key:
sdljflase;ru2u3
--generate-signature : Generate a signature for a file and output it to the console. Example use: --generate-signature path/to/app/MyApp.exe . Outputs in format: Signature: seljr13412zpdfj . Note that these options are only for verifying Ed25519 signatures. For DSA signatures, please use the DSAHelper tool. Both of the following options must be used together. You must have keys already generated in order to verify file signatures.
--verify : Path to the file that has a signature you want to verify.--signature : Base 64 signature of the file. Example use: --verify my/path/MyApp.exe --signature 123l4ijsdfzderu23 .
This will return either Signature valid (signature is good!) or Signature invalid (signature does not match file).
# ### Key Generation
# Generate Ed25519 keys for the first time
netsparkle-generate-appcast --generate-keys
# Store keys in a custom location
netsparkle-generate-appcast --key-path path/to/store/keys
# Pass in public key via command line
netsparkle-generate-appcast --public-key-override [YourPublicKeyHere]
# Pass in private key via command line
netsparkle-generate-appcast --private-key-override [YourPrivateKeyHere]
# By default, your Ed25519 signatures are stored on disk in your local
# application data folder in a subdirectory called `netsparkle`.
# If you want to export your keys to the console, you can do:
netsparkle-generate-appcast --export
# You can also store your keys in the following environment variables:
# set public key: SPARKLE_PUBLIC_KEY
# set private key: SPARKLE_PRIVATE_KEY
# ### Generate a signature for a binary without creating an app cast:
netsparkle-generate-appcast --generate-signature path/to/binary.exe
# ### Verifying Binaries
netsparkle-generate-appcast --verify path/to/binary.exe --signature base_64_signature
# ### Using a custom key location:
# If your keys are sitting on disk somewhere
# (`NetSparkle_Ed25519.priv` and `NetSparkle_Ed25519.pub` -- both
# in base 64 and both on disk in the same folder!), you can pass in
# the path to these keys like this:
netsparkle-generate-appcast --key-path path/to/keys/
# ### Generating an app cast
# Generate an app cast for Windows executables that are sitting in a
# specific directory
netsparkle-generate-appcast -a directory/for/appcast/output/ -e exe -b directory/with/binaries/ -o windows
# Add change log info to your app cast
netsparkle-generate-appcast -b binary/folder -p change/log/folder
# Customize download URL for binaries and change logs
netsparkle-generate-appcast -b binary/folder -p change/log/folder -u https://example.com/downloads -l https://example.com/downloads/changelogs
# Set your application name for the app cast
netsparkle-generate-appcast -n " My Awesome App " -b binary/folder
# Use file versions in file names, e.g. for apps like "My App 1.2.1.dmg"
netsparkle-generate-appcast -n " macOS version " -o macos -f true -b binary_folder -e dmg
# Don't overwrite the entire app cast file
netsparkle-generate-appcast --reparse-existing
# Don't overwrite the entire app cast file, but do overwrite items that are still on disk
netsparkle-generate-appcast --reparse-existing --overwrite-old-itemsPlease see the UPGRADING.md file for information on breaking changes and fixes between major versions.
Non. You can just reference the core library and handle everything yourself, including any custom UI. Check out the code samples for an example of doing that!
This isn't a built-in feature, as NetSparkleUpdater assumes that it can safely make calls/events to the UI on the thread that started the SparkleUpdater instance. However, if you'd like to do this, we have a sample on how to do this: NetSparkle.Samples.Forms.Multithread . Basically, instead of passing in a UIFactory to SparkleUpdater , you handle SparkleUpdater 's events yourself and show the UI however you want to show it - and yes, you can still use the built-in UI objects for this!
(Note that on Avalonia, the answer is always "No" since they only support one UI thread at this time.)
Oui. You need to start the NetSparkleUpdater forms on a new thread(s). See the NetSparkle.Samples.Forms.Multithread sample for how to do this by handling events yourself and still using the built-in WinForms UIFactory .
See #238 and this documentation for the fix for making this work on the sample application. Basically, you need to use an app config file and manifest file to let Windows know that your application is DPI-aware. If that doesn't work for you, try some of the tips at this SO post.
Oui!
--os command line parameter.macos-arm64 or windows-x64 rather than just macos or windows Trimming is a great way to reduce the file size of your application when it is self-published and/or built as a self-contained application. In short, trimming removes unused code from your applications, including external libraries, so you can ship your application with a reduced file size. To trim your application on publish, add <PublishTrimmed>true</PublishTrimmed> to your csproj file. If you want to trim all assemblies (including those that may not have specified they are compatible with trimming), add <TrimMode>full</TrimMode> to your csproj file; to only trim those that have opted-in, use <TrimMode>partial</TrimMode> . To enable warnings for trimming, add <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings> .
There are other options to use, which you can learn more about on Microsoft's documentation here. For those applications that may not work with the built-in trimming options, please try Zack.DotNetTrimmer or other solutions you may find.
We recommend that you trim your application before publishing it and distributing it to your users. Some of NetSparkle's default dependencies are rather large, but the file size can be drastically reduced by the trim process. If you choose to trim your application, don't forget to test it after trimming and make sure you fix any warnings that come up!
You can also read more about trimming libraries here.
Oui.
Oui.
Oui. In the app cast generator, you can do things like, -u ../ to make NetSparkle check the directory above the server's appcast.xml file for download files.
NetSparkleUpdater.SparkleUpdater is the right package if you want the library with no built-in UI. Otherwise, use NetSparkleUpdater.UI.{YourChoiceOfUI} , which will give you a built-in UI and the core library. Previous to 2.0, the UI libraries reference NetSparkle.New , which is now deprecated.
Here is the full list of deprecated packages:
com.pikleproductions.netsparkle -- replaced by NetSparkleUpdater.SparkleUpdatercom.pikleproductions.netsparkle.tools -- replaced by NetSparkleUpdater.Tools.AppCastGenerator and NetSparkleUpdater.Tools.DSAHelperNetSparkle.New -- replaced by NetSparkleUpdater.SparkleUpdaterNetSparkle.New.Tools -- replaced by NetSparkleUpdater.Tools.AppCastGenerator and NetSparkleUpdater.Tools.DSAHelperNetSparkleUpdater.Tools -- replaced by NetSparkleUpdater.Tools.AppCastGenerator and NetSparkleUpdater.Tools.DSAHelperNo. If your app is just using NetSparkle to work out if there is a later release - and you are not using the app cast as a way to refer to historical versions of your app in any way - then you don't need to add all the released versions into the app cast file.
Having just the latest version of your software in the app cast has the added side effect that you won't need all the binaries & changelogs of all the versions to be available to the app cast generator tool. For example, this might make an automated release build easier via GitHub Actions - because the only data required is the generated .exe and changelogs from your git repository.
SecurityMode.Unsafe or the following IAppCastHandler override: public override bool DownloadAndParse ( )
{
try
{
_logWriter . PrintMessage ( "Downloading app cast data..." ) ;
var appCast = _dataDownloader . DownloadAndGetAppCastData ( _castUrl ) ;
if ( ! string . IsNullOrWhiteSpace ( appCast ) )
{
Items . Clear ( ) ;
Items . AddRange ( ParseAppCast ( appcast ) ) ;
return true ;
}
}
catch ( Exception e )
{
_logWriter . PrintMessage ( "Error reading app cast {0}: {1} " , _castUrl , e . Message ) ;
}
return false ;
}The answer is both yes and no. No, because that is not the default behavior. Yes, because if you use installers for each of your versions, you can use your app cast to see which previous versions are available and download those versions. If your installers are standalone, they should install an old version just fine. Just keep in mind that if you install an old version and then there is a newer version in your app cast, after opening the older software, it will ask them if they want to update to the newer version!
Here's a summary of what you can do:
SparkleUpdater object_updateInfo = await _sparkle.CheckForUpdatesQuietly(); (no UI shown) or _sparkle.CheckForUpdatesAtUserRequest() (shows UI). I would recommend checking quietly because the UI method will always show the latest version. You can always show your own UI._updateInfo.Updates for the available versions in your app cast. You can compare it with your currently installed version to see which ones are new and which ones are old.await _sparkle.InitAndBeginDownload(update); with the update you want to download. The download path is provided in the DownloadFinished event._sparkle.InstallUpdate(update, _downloadPath);The Handle Events Yourself sample and the Rollback sample will be very helpful to you in learning how to do these sort of things.
Oui. Implement IAppCastGenerator and set the SparkleUpdater.AppCastGenerator property to an instance of your class. You will have to implement the following methods:
AppCast DeserializeAppCast ( string appCastString ) ;
Task < AppCast > DeserializeAppCastAsync ( string appCastString ) ;
AppCast DeserializeAppCastFromFile ( string filePath ) ;
Task < AppCast > DeserializeAppCastFromFileAsync ( string filePath ) ;
string SerializeAppCast ( AppCast appCast ) ;
Task < string > SerializeAppCastAsync ( AppCast appCast ) ;
void SerializeAppCastToFile ( AppCast appCast , string outputPath ) ;
Task SerializeAppCastToFileAsync ( AppCast appCast , string outputPath ) ; As you can see, many of those functions are small variants of the core serialization and deserialization processes that you want to accomplish. You can look at the implementation of JsonAppCastGenerator and XMLAppCastGenerator for implementation examples.
Oui. Implement IAppCastGenerator and set the SparkleUpdater.AppCastGenerator property to an instance of your class. You'll have to make the actual app cast file yourself, though, since the app cast generator is only currently compatible with XML and JSON.
Right now, we are compatible with version 11. If you need to make changes, you can use your own IUIFactory implementation to fix any issues that come up.
DSA signatures are not recommended when using NetSparkleUpdater 2.0+. They are considered insecure!
You can still generate/use these signatures, however, using the DSAHelper tool (from this NuGet package or in the source code here). Key generation only works on Windows because .NET Core 3 does not have the proper implementation to generate DSA keys on macOS/Linux; however, you can get DSA signatures for a file on any platform. If you need to generate a DSA public/private key, please use the DSAHelper tool on Windows like this:
netsparkle-dsa /genkey_pair
You can use the DSAHelper to get a signature like this:
netsparkle-dsa /sign_update {YourInstallerPackage.msi} {NetSparkle_PrivateKey_DSA.priv}
dotnet tool install --global NetSparkleUpdater.Tools.DSAHelpernetsparkle-dsa command Pass a DSAChecker into your SparkleUpdater constructor rather than an Ed25519Checker .
If your app has DSA signatures, the app cast generator uses Ed25519 signatures by default starting with preview 2.0.0-20200607001 . To transition to Ed25519 signatures, create an update where the software has your new Ed25519 public key and a NEW url for a NEW app cast that uses Ed25519 signatures. Upload this update with an app cast that has DSA signatures so your old DSA-enabled/containing app can download the Ed25519-enabled update. Then, future updates and app casts should all use Ed25519.
Here are some things you can do to figure out how to get your app running:
SparkleUpdater.LogWriter = new LogWriter(LogWriterOutputMode.Console) and then watch your console output while debugging.Oui! Please help us make this library awesome!
NetSparkle is available under the MIT License.
Contributions are ALWAYS welcome! If you see a new feature you'd like to add, please open an issue to talk about it first, then open a PR for that implementation. If there's a bug you find, please open a PR with the fix or file an issue! Merci!! :) You can also join us in our Gitter chat room!
An incomplete list of other projects related to software updating that you might want to look at if NetSparkleUpdater doesn't work for you: