
Un marco de actualización de software fácilmente personalizable para proyectos C# .NET con UI incorporadas para WinForms, WPF y Avalonia
Netsparkle es un marco de actualización de software altamente configurable para C# que es compatible con .NET 6+ y .NET Framework 4.6.2+, tiene UIS pre-construidos para .NET Framework (WinForms, WPF) y .NET 6+ (WinForms, WPF, Avalonia), usa ED25519 u otras firmas criptográficas, y incluso UIS de UIS o no. Usted proporciona, en algún lugar de Internet, una aplicación de la aplicación con información de actualización e versión, junto con las notas de versión en formato Markdown o HTML. Esta biblioteca luego le ayuda a verificar una actualización, mostrar al usuario las notas de la versión y ofrecer descargar/instalar la nueva versión del software.
Tipos de descarga de actualización compatibles con compatible:
Consulte Actualizar.MD para obtener información sobre los principales cambios de versión, actualizaciones, etc.
Netsparkle está disponible a través de Nuget. Para elegir un paquete Nuget para usar:
NetSparkleUpdater.SparkleUpdater package central.| Paquete | Caso de uso | Liberar | Avance | Descargas |
|---|---|---|---|---|
| Netsparkleupdater.sparkleupdater | Paquete central; Use una interfaz de usuario 100% personalizada o sin interfaz de usuario (nada incorporado) | |||
| WinForms UI (.NET Framework) | Netsparkle con ui de winforms incorporado | |||
| WinForms UI (.NET 6+) | Netsparkle con ui de winforms incorporado | |||
| WPF UI (.NET Framework y .NET 6+) | Netsparkle con UI WPF incorporado | |||
| Avalonia ui | Netsparkle con UI de Avalonia incorporada | |||
| Herramienta del generador de reparto de aplicaciones | Herramienta CLI netsparkle-generate-appcast (incluido ED25519 ayudantes) | |||
| Herramienta de ayuda de DSA | Herramienta de CLI netsparkle-dsa (ayudantes de DSA) |
Información rápida para instalaciones de herramientas:
dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator ; Disponible como netsparkle-generate-appcast en su línea de comando después de la instalacióndotnet tool install --global NetSparkleUpdater.Tools.DSAHelper ; Disponible como netsparkle-dsa en su línea de comando después de la instalación Una ruta de actualización de software típica para una pieza de software estereotípica podría verse así:
dotnet publish )En este momento, Netsparkleupdater no te ayuda con 1., 2. o 4. "¿Por qué no?", Podrías preguntar:
sudo por cualquier razón, hay un ejemplo de hacerlo en la muestra de MacOS Avalonia .Para crear el archivo de reparto de su aplicación, consulte la sección de reparto de la aplicación de este documento.
Estamos abiertos a contribuciones que puedan facilitar el proceso de instalación/actualización general para el usuario. Primero presente un problema con su idea antes de comenzar a trabajar para que podamos hablar de ello.
¡Mire los proyectos de muestra en este repositorio para muestras de uso básicas y ejecutables! ¡Hay muestras sobre el uso de cada una de las UI incorporadas, así como una muestra de "hazlo tú mismo en tu propia interfaz de usuario"!
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 o forma principal o similar: 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 archivo DMG (Linux), un archivo .tar.gz (Linux) o similar. Más información en la sección de trabajo de cómo actualizaciones.netsparkle-generate-appcast --help para opciones): netsparkle-generate-appcast -b binary/folder -p change/log/folder -u https://example.com/downloads -l https://example.com/downloads/changelogs.signature o archivos similares) a las ubicaciones apropiadas en su servidorSparkleUpdater.LogWriter para ver si hay alguna información de depuración útil que se muestre en la consola! En su archivo de proyecto, asegúrese de configurar algunas cosas para que la biblioteca pueda leer en los detalles pertinentes más adelante. Nota: Puede usar su propio IAssemblyAccessor para cargar información de versión de otro lugar. Sin embargo, configurar las cosas en el archivo de su proyecto es fácil, ¡y NetsParkleUpdater puede leer eso de forma nativa!
< 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 > Nota importante: en .NET 8+, se realizó un cambio en el núcleo de .NET que hace que su GIT/código fuente compromiera el hash que se incluya en el número <Version> de su aplicación. NetsParkleUpdater no puede evitar este comportamiento en este momento, ya que confiamos en AssemblyInformationalVersionAttribute , y el comportamiento de este atributo se cambió. A sus usuarios se les puede decir que actualmente están ejecutando 1.0.0+commitHashHere por NetsParkleupdater (¡y su aplicación natal en sí!). También recomendamos agregar las siguientes líneas a su archivo de proyecto (en un nuevo <PropertyGroup> o uno existente):
< 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!En el primer evento de aplicación.idle, el archivo XML de reparto de su aplicación se descargará, leerá y se comparará con la versión en ejecución actualmente. Si tiene una actualización de software en el interior, se le notificará al usuario con una pequeña notificación de tostadas (si es compatible con la interfaz de usuario y habilitado) o con un diálogo de actualización que contiene sus notas de versión. El usuario puede ignorar la actualización, solicitar que se le recuerde más tarde, o descargarla/instalarla ahora.
Si desea verificar una actualización en segundo plano sin que el usuario vea nada, use
var updateInfo = _sparkle . CheckForUpdatesQuietly ( ) ;Si desea tener un elemento de menú para que el usuario busque actualizaciones para que el usuario pueda ver la interfaz de usuario mientras Netsparkle busca actualizaciones, use
_sparkle . CheckForUpdatesAtUserRequest ( ) ;Si tiene archivos que necesitan guardar, suscríbase al evento PreparingToExit:
_sparkle . PreparingToExit += ( ( x , cancellable ) =>
{
// ask the user to save, whatever else is needed to close down gracefully
} ) ; Tenga en cuenta que si no usa un UIFactory , debe usar los eventos CloseApplication o CloseApplicationAsync para cerrar su aplicación; De lo contrario, su archivo de actualización descargado nunca se ejecutará/leerá. La única excepción a esto es si desea manejar todos los aspectos de la instalación del paquete de actualización usted mismo.
¡El archivo que inicia su ejecutable de actualización descargada solo espera 90 segundos antes de rendirse! ¡Asegúrese de que su software se cierre dentro de los 90 segundos del cierre de cierre/cierre de cierre que se llama si implementa esos eventos! Si necesita un evento que pueda cancelarse, como cuando se le debe preguntar al usuario si está bien cerrar (por ejemplo, para guardar su trabajo), use PreparingForExit o PreparingToExitAsync .
IUIFactory ; Establezca SparkleUpdater.UIFactory para utilizar una instancia de su objeto.ICheckingForUpdates para su interfaz de usuario que le indique al usuario que SparkleUpdater está verificando las actualizacionesIDownloadProgress para su interfaz de usuario que muestra al usuario que se está descargando una actualizaciónIUpdateAvailable para su interfaz de usuario que muestre al usuario que una actualización está disponible junto con las notas de versiónIAppCastDataDownloader para configurar sus propios métodos para descargar datos de reparto de aplicaciones; establecer SparkleUpdater.AppCastDataDownloader para utilizar una instancia de su objeto. Netsparkle incluye dos implementaciones de forma predeterminada: WebRequestAppCastDataDownloader para descargar la información de reparto de aplicaciones de Internet en general, y LocalFileAppCastDownloader para copiar/"descargar" una aplicación de una aplicación de una ruta dada dadaIAppCastFilter para realizar un filtrado personalizado en los objetos AppCastItem en el reparto de su aplicación descargada, por ejemplo, para considerar solo un subconjunto dado de elementos como actualizaciones válidas para su aplicación; Establezca AppCastHelper.AppCastFilter ( SparkleUpdater.AppCastHelper.AppCastFilter ) para utilizar una instancia de su objeto. Netsparkle incluye la clase ChannelAppCastFilter , que puede usar para filtrar elementos mediante un canal de producto dado (por ejemplo, alfa, beta) si su aplicación utiliza esas características.IAppCastGenerator para controlar cómo se serializan y deserializan los moldes de aplicaciones; Establezca SparkleUpdater.AppCastGenerator para utilizar una instancia de su objeto. Netsparkle incluye dos implementaciones: XMLAppCastGenerator , para serialización/deserialización XML; y JsonAppCastGenerator , para la serialización/deserialización de JSON. La herramienta CLI del generador de reparto de la aplicación también puede generar fundiciones de aplicaciones XML y JSON.IAssemblyAccessor para controlar cómo se cargan la versión, los derechos de autor y otros detalles del producto para su aplicación; Establecer Configuration.AssemblyAccessor ( SparkleUpdater.Configuration.AssemblyAccessor ) para utilizar una instancia de su objeto. Netsparkle contiene una implementación predeterminada, AssemblyDiagnosticsAccessor , que debería funcionar en el caso general de carga de datos de un ensamblaje determinado.ILogger y establezca SparkleUpdater.LogWriter . Por defecto, se usa la clase LogWriter (que tiene la propiedad LogWriterOutputMode para controlar si los registros están escritos en Console , Trace , etc.)ISignatureVerifier para cambiar la forma en que se manejan sus firmas para el elenco de la aplicación, las descargas, etc.; Establezca SparkleUpdater.SignatureVerifier para utilizar una instancia de su objeto.IUpdateDownloader para configurar sus propios métodos para descargar y enviar progreso en los archivos de actualización de la aplicación (por ejemplo, instaladores) para un elemento de reparto de la aplicación determinada; Establezca SparkleUpdater.UpdateDownloader para utilizar una instancia de su objeto. Netsparkle incluye dos implementaciones de forma predeterminada: WebFileDownloader (predeterminado) descargar archivos desde la web/Internet, y LocalFileDownloader para copiar/"descargar" un archivo desde una ruta dada. Configuration de subclase Para cambiar cómo cierta información de NetSparkle se guarda y carga, por ejemplo, la información de la versión omitida. Esta clase es la que utiliza una instancia IAssemblyAccessor para guardar y cargar información de la versión, nombre del producto, etc. Netsparkle contiene tres implementaciones: RegistryConfiguration , que guarda y carga información en el Registro de Windows (predeterminado en Windows); JSONConfiguration , que guarda y carga información a un archivo JSON (predeterminado en MacOS/Linux); y DefaultConfiguration , que no hace nada y sirve como alternativa en caso de que JSONConfiguration no pueda encontrar una ubicación de archivo válida para guardar y cargar datos. Para usar la instancia de su clase, establezca SparkleUpdater.Configuration .RegistryConfiguration de subclasificación le permite cambiar rápidamente la ruta del registro donde los elementos se guardan a través de BuildRegistryPathJSONConfiguration le permite cambiar rápidamente la ruta del archivo donde los datos se guardan a través de GetSavePathAppCastHelper Si desea control total sobre el proceso de descarga y análisis de la aplicación de la aplicación. Tenga en cuenta que probablemente pueda hacer todo lo que necesita hacer a través de las propiedades AppCastHelper (incluida IAppCastFilter AppCastFilter ), pero el subclase le dará un control total y absoluto sobre todo el proceso. Para usar la instancia de su clase, configure SparkleUpdater.AppCastHelper .ReleaseNotesGrabber para controlar el proceso de descarga de notas (y, por lo tanto, mostrar). Para usar una instancia de su clase, establezca UIFactory.ReleaseNotesGrabberOverride .WebFileDownloader si no desea implementar IUpdateDownloader usted mismo y solo desea anular una función o dos, como CreateHttpClient o RetreiveDestinationFileNameAsync . Para usar una instancia de su clase, configure SparkleUpdater.UpdateDownloader .WebRequestAppCastDataDownloader si no desea implementar IAppCastDataDownloader y solo desea anular una función o dos como CreateHttpClient . Para usar una instancia de su clase, configure SparkleUpdater.AppCastDataDownloader .LogWriter para implementar la función PrintMessage ; Debido a que ILogger es una interfaz bastante simple, probablemente pueda implementar esa interfaz usted mismo si sus necesidades son complejas. Para usar una instancia de su clase, configure SparkleUpdater.LogWriter .SparkleUpdater para implementar algunas funciones relacionadas con la instalación diferentes, que incluyen:GetWindowsInstallerCommandGetInstallerCommandRunDownloadedInstallerGetDownloadPathForAppCastItemUIFactory si no desea implementar la totalidad de la interfaz IUIFactory usted mismo y solo desea configurar una función o dos. Para usar una instancia de su clase, establezca SparkleUpdater.UIFactory . IAppCastFilter Puede cambiar la forma en que los elementos de reparto de su aplicación se filtran a través de la propiedad AppCastHelper.AppCastFilter (a través de la interfaz IAppCastFilter ). Esto le permite cambiar los artículos disponibles para sus usuarios finales.
NetSparkle contiene una implementación incorporada IAppCastFilter para el filtrado basado en canales llamado ChannelAppCastFilter . Para algunos ejemplos sobre cómo usar esa clase, consulte las pruebas unitarias aquí. Básicamente, establezca la propiedad List<string> ChannelSearchNames en los canales por los que desea filtrar. Si desea mantener elementos sin información de canal (por ejemplo, 1.2.3 ), establezca KeepItemsWithNoChannelInfo en true .
Para configurar los canales en su aplicación de elementos / en el reparto de su aplicación, use la propiedad --channel de la herramienta CLI de la aplicación de la aplicación, o establezca la propiedad <Version> de su archivo de proyecto en la versión compatible con Semver aplicable (por ejemplo, <Version>1.0.2-beta1</Version> ), y la herramienta CLI de la aplicación se recogerá automáticamente. O, si está construyendo su elenco de aplicación manualmente, configure el <sparkle:channel>YourChannelHere</sparkle:channel> propiedad en su <item> (o, si usa JSON, la propiedad channel ).
NetsParkleupdater no tiene que usarse con una interfaz de usuario. Puede hacer todo usted mismo o incluso hacer que la biblioteca ejecute su actualización descargada automáticamente configurando SparkleUpdater.UserInteractionMode = UserInteractionMode.DownloadAndInstall . Este repositorio tiene una muestra sobre hacer las cosas usted mismo sin ninguna interfaz de usuario preconstruida en src/netsparkle.samples.handleeventsyourself.
Si desea una interfaz de usuario, ofrecemos UI pre-construidas en diferentes paquetes Nuget con una pequeña cantidad de opciones personalizables para Winforms, WPF y Avalonia. Las UI se activan a través de una implementación IUIFactory , llamada UIFactory en cada una de las opciones incorporadas. La mayoría de los métodos en el UIFactory se pueden anular si desea ajustar el comportamiento, y el ProcessWindowAfterInit le permite personalizar cada ventana después de que se realice.
Si desea rodar su propia interfaz de usuario por completo, simplemente implemente la interfaz IUIFactory con cualquier biblioteca de interfaz de usuario que desee usar. Puede copiar o reutilizar los modelos de vista, el código, etc. de las opciones prebuiladas de NetsParkleUpdater, y copiar+código de pegado de este repositorio en el suyo es probablemente una buena forma rápida de comenzar. ¡No olvides establecer el SparkleUpdater.UIFactory propiedad con una instancia de su implementación IUIFactory !
Tenga en cuenta: Netsparkle básicamente no hace intentos de preocuparse por el enhebrado (por ejemplo, llamar al hilo principal), excepto por el bucle de fondo que llama al hilo principal que inició la instancia SparkleUpdater . En otras palabras, en términos generales, Netsparkle hará todo en el hilo que originalmente creó la instancia SparkleUpdater . Para la mayoría de las aplicaciones, esto estará bien ya que solo están usando su hilo de interfaz de usuario principal. En caso de duda, para sus propias necesidades de la interfaz de usuario, asegúrese de verificar InvokeRequired en Winforms, y en WPF/Avalonia, las cosas de Marshal al hilo de la interfaz de usuario (a menos que esté utilizando el enlace de datos en cuyo caso se maneja para usted!).
Pasar su propia implementación IUIFactory que inicia Windows/cosas en nuevos hilos en SparkleUpdater no es una configuración compatible. Si desea ejecutar su propia interfaz de usuario en múltiples hilos (por ejemplo, para que WinForms no tenga las ventanas de Netsparkleupdater cierran cuando se cierre el formulario principal), hágalo usando los eventos de SparkleUpdater y no el UIFactory ; Consulte también la muestra SRC/Netsparkle.samples.forms.multithread para un ejemplo práctico de cómo hacer esto.
El elenco de la aplicación es solo un archivo XML o JSON. Contiene campos como el título y la descripción de su producto, así como una definición por versión de su software.
Recomendamos encarecidamente que haga uso de la herramienta NetsParkle-Generate-Apcast para crear (y más tarde, recrear/actualizar) el archivo porque puede ayudar a ocuparse de todos los requisitos de firma para usted.
dotnet tool install --global NetSparkleUpdater.Tools.AppCastGeneratornetsparkle-generate-appcast . Puede usar netsparkle-generate-appcast --help para ver una lista completa de opciones para esta herramienta. Por defecto, Netsparkle utiliza moldes de aplicaciones XML compatibles con Sparkle en su mayor parte . NetsParkle usa sparkle:signature en lugar de sparkle:edSignature para que pueda elegir cómo firmar sus archivos/reparto de aplicaciones. (Si desea usar sparkle:edSignature , Pass --use-ed25519-signature-attribute al generador de reparto de la aplicación). Tenga en cuenta que Netsparkle es compatible y usa las firmas de ED25519 de forma predeterminada, pero el marco puede manejar una implementación diferente de la clase ISignatureVerifier para verificar diferentes tipos de firmas sin una versión de la versión principal.
Aquí hay un reparto de aplicación XML de muestra:
<? 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 lee las etiquetas <item> para determinar si las actualizaciones están disponibles.
Las etiquetas importantes en cada <item> son:
<description><sparkle:releaseNotesLink> .<sparkle:releaseNotesLink><description> está presente, se usará en su lugar.sparkle:signature , opcional: la firma DSA/ED25519 del documento; Netsparkle no verifica esta firma para usted a menos que establezca ReleaseNotesGrabber.ChecksReleaseNotesSignature en true , pero puede verificar manualmente las firmas de ChangELog si le gusta o establece ReleaseNotesGrabber.ChecksReleaseNotesSignature = true en su UI.<pubDate>sparkle:channel : Canal para este elemento de reparto de la aplicación, por ejemplo, beta (no requerido) - solo acepta 1 canal<enclosure>url : URL del archivo de actualizaciónsparkle:version : número de versión legible por máquina de esta actualizaciónlength , opcional: (no validado) Tamaño del archivo de actualización en bytestype : ignoradosparkle:signature : DSA/ED25519 Firma del archivo de actualizaciónsparkle:criticalUpdate , opcional: si es igual a true o 1 , la interfaz de usuario indicará que esta es una actualización críticasparkle:os : sistema operativo para el elemento de reparto de la aplicación. El valor predeterminado a Windows si no se suministra. Para Windows, use "Win" o "Windows"; Para macOS, use "macOS" o "OSX"; Para Linux, use "Linux". Por defecto, necesita 2 firmas ( SecurityMode.Strict ):
sparkle:signature="..." )Nota: La herramienta Generador de reparto de la aplicación crea ambas firmas para usted cuando recrea el archivo Appcast.xml.
Puede generar firmas ED25519 utilizando la herramienta AppCastGenerator (desde este paquete Nuget o en el código fuente aquí). Esta herramienta requiere que el tiempo de ejecución de escritorio .NET 6, 7, 8 o 9 se instale. Consulte las secciones a continuación para opciones y ejemplos sobre la generación de las claves ED25519 y para usarlas al crear un reparto de aplicación.
AppCastGenerator (de este paquete Nuget o en el código fuente aquí) para crear fácilmente su archivo de reparto de aplicación. Las opciones disponibles se describen a continuación. Puede instalarlo en su CLI a través de dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator .string.Format o similar es algo maravilloso).Si desea usar un elenco de aplicación JSON en lugar de XML:
--output-type json al generar su archivo de reparto de aplicación a través del generador de reparto de la aplicaciónSparkleUpdater.AppCastGenerator en new JsonAppCastGenerator(mySparkleUpdater.LogWriter) .JsonAppCastGenerator.HumanReadableOutput en false .¿Te falta alguna opción que te gustaría ver? ¡File un problema en este repositorio o agréguelo usted mismo y envíenos una solicitud de extracción!
--show-examples : Imprima ejemplos de uso en la consola.--help : Muestre todas las opciones y sus descripciones. -a / --appcast-output-directory : Directorio en el que escribir el archivo de salida appcast.xml . Ejemplo de uso: -a ./MyAppCastOutput-e / --ext : cuando busque archivos para agregar a la elección de la aplicación, use la (s) extensión (s) dada (s) cuando busque archivos. El valor predeterminado a exe . Ejemplo de uso: -e exe,msi-b / --binaries : ruta de archivo al directorio que se debe buscar al buscar archivos para agregar al reparto de la aplicación. Predeterminado a . . Ejemplo de uso: -b my/build/directory-r / --search-binary-subdirectories : cierto para buscar el directorio binario recursivamente para binarios; falso para buscar solo el directorio superior. El valor predeterminado es false . Ejemplo de uso: -r .--single-file : un solo archivo para agregar al reparto de la aplicación-si se establece, --binaries , --ext , etc. se ignoran. Útil para usar si su archivo de salida no tiene extensión (por ejemplo, es un ejecutable de UNIX). Ejemplo de uso: --single-file path/to/my/file-f / --file-extract-version : si extrae o no la versión del archivo del nombre del archivo en lugar del archivo (por ejemplo, DLL) en sí. El valor predeterminado es false . Use cuando sus archivos que serán descargados por NetsParkleUpdater tendrán el número de versión en el nombre del archivo, por ejemplo, "mi aplicación 1.3.2-alfa1.exe". Tenga en cuenta que esto solo busca los últimos cuatro elementos/carpetas de directorio. Ejemplo de uso: -f true--file-version : use para establecer la versión para un binario que entra en un reparto de aplicación. Tenga en cuenta que esta versión solo se puede configurar una vez, por lo que al generar un reparto de aplicación, asegúrese de que: a) tenga solo un binario en su elenco de aplicación | B) Utilice el parámetro --reparse-existing para que los elementos viejos sean recogidos. Si el generador encuentra 2 binarios sin ninguna versión conocida y se establece --file-version , entonces se emitirá un error. Ejemplo de uso: --file-version 1.3.2-o / --os : sistema operativo al que pertenecen los elementos de la aplicación. La cadena debe incluir uno de los siguientes: windows , mac , linux . Predeterminado a windows . Ejemplo de uso: -o macos-arm64 ; -o windows-x64--description-tag : texto para poner en la aplicación Etiqueta/información de descripción del elenco. El valor predeterminado es "cambios más recientes con enlaces a actualizaciones". Ejemplo de uso: --description-tag "Hello I am a Cool App"--link-tag : texto para poner en la etiqueta/información link de reparto de la aplicación. Debe ser su aplicación URL Descargar el elenco si usa esto. Ejemplo de uso: --link-tag https://mysite.com/coolapp/appcast.xml-u / --base-url : parte inicial de la URL para usar para descargas. El nombre del archivo que se descargará se pondrá después de esta parte de la URL. Ejemplo de uso: -u https://myawesomecompany.com/downloads-l / --change-log-url : parte inicial de la URL para usar para sus archivos de registro de cambio. El archivo de registro de cambio que se descargará se colocará después de esta parte de la URL. Si no se especifica esta opción, los datos de registro de cambio se colocarán en la aplicación de la aplicación. Ejemplo de uso: -l https://myawesomecompany.com/changes-p / --change-log-path : ruta a los archivos de registro de cambio para su software. Se espera que estos estén en formato de marcado con una extensión de .md . El nombre del archivo de los archivos de registro de cambio debe contener la versión del software, por ejemplo, 1.3.2.md Ejemplo de uso: -p path/to/change/logs . (Nota: El generador también intentará encontrar registros de cambio cuyos nombres de archivos están formateados como: MyApp 1.3.2.md )--change-log-name-prefix : prefijo para cambiar los nombres de archivo de registro. Por defecto, el generador busca nombres de archivo con el formato "[Versión] .md". Si establece este parámetro en (por ejemplo) "mi aplicación de cambio de aplicación", buscará nombres de archivos con el formato "mi aplicación cambia log [versión] .md", así como "[versión] .md".-n / --product-name : nombre del producto para su software. Utilizado al configurar el título para el elenco de su aplicación y sus elementos. El valor predeterminado a Application . Ejemplo de uso: -n "My Awesome App"-x / --url-prefix-version : Agregue el número de versión como prefijo al nombre del archivo para la URL de descarga. El valor predeterminado es falso. Por ejemplo, si --base-url es www.example.com/downloads , su versión es 1.4.2 y su nombre de aplicación es MyApp.exe , su URL de descarga se convertirá en www.example.com/downloads/1.4.2/MyApp.exe . Ejemplo de uso: -x true .--key-path : ruta a NetSparkle_Ed25519.priv y NetSparkle_Ed25519.pub Archivos, que son sus claves PRIVADAS y PRIVASES ED255519 para sus actualizaciones de software, respectivamente. Ejemplo de uso: --key-path my/path/to/keysSPARKLE_PRIVATE_KEY y SPARKLE_PUBLIC_KEY antes de ejecutar generate_appcast . ¡La herramienta prioriza las teclas de entorno sobre las teclas sentadas en el disco!--signature-file-extension (sin el . ) Para usar para el archivo de firma de la aplicación. El valor predeterminado a signature . Ejemplo de uso: --signature-file-extension txt .--output-file-name : nombre de archivo de salida para la aplicación emitida con el . o la extensión. La extensión se controla si se trata de una salida XML o JSON y no es configurable. El valor predeterminado es 'AppCast'. Por supuesto, siempre puedes cambiar esto más adelante después de que se haya generado el elenco de la aplicación; Esta opción es solo por conveniencia. Ejemplo de uso: --output-file-name super_app_download_info .--use-ed25519-signature-attribute : si es verdadero y realizando la salida XML, el atributo de firma de salida en el XML será edSignature en lugar signature para que coincida con la biblioteca Sparkle original. No hay efecto en los moldes de aplicaciones JSON.--file-version : use para establecer la versión para un binario que entra en un reparto de aplicación. Tenga en cuenta que esta versión solo se puede configurar una vez, por lo que al generar un reparto de aplicación, asegúrese de que: a) tenga solo un binario en su elenco de aplicación | B) Utilice el parámetro --reparse-existing para que los elementos viejos sean recogidos. Si el generador encuentra 2 binarios sin ninguna versión conocida y se establece --file-version , entonces se emitirá un error.--critical-versions : lista de versiones separadas por comas para marcar como crítica en el reparto de la aplicación. Debe coincidir con el texto de la versión exactamente. Por ejemplo, "1.0.2,1.2.3.1".--reparse-existing : vuelva a ser parpadeante de una aplicación existente en lugar de anularla y crearla de nuevo. Sobre las versiones que ya están en el elenco de la aplicación, por lo que si implementa un nuevo binario con la misma versión, deberá editar manualmente su elenco de aplicación para eliminar la lista anterior de la versión que está reproduciendo. Ejemplo de uso: --reparse-existing true--overwrite-old-items : hace que los elementos de reparto de la aplicación se reescriban en el reparto de la aplicación si se encuentra el binario en disco con el mismo número de versión. En otras palabras, si 1.0.1 ya está en la aplicación repartida (ya sea de autorización o de otro binario), y otro 1.0.1 se encuentra en el disco, entonces los datos 1.0.1 en el reparto de la aplicación se reescribirán en función del binario encontrado. Tenga en cuenta que esto significa que si tiene múltiples versiones 1.0.1 en el disco (que no debe hacer ...), ¡el último encontrado será el de su elenco de aplicación! Ejemplo de uso: --overwrite-old-items--human-readable : si es verdadero, hace que el archivo de reparto de la aplicación de salida sea legible (líneas de noticias, sangrías). Ejemplo de uso: --human-readable true--channel : Nombre del canal de lanzamiento para cualquier elemento agregado en el reparto de la aplicación. Debe ser un solo 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.
No. 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.)
Sí. 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.
¡Sí!
--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.
Sí.
Sí.
Sí. 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.
Sí. 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.
Sí. 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.¡Sí! 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! ¡¡Gracias!! :) 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: