
Uma estrutura de atualização de software facilmente personalizável para projetos C# .NET com UIs embutidas para WinForms, WPF e Avalonia
O NetsParkle é uma estrutura de atualização de software altamente configurável para C# que é compatível com a estrutura .NET 6+ e .NET 4.6.2+, possui UIs pré-construídas para .NET Framework (WinForms, WPF) e UMATH. Você fornece, em algum lugar da Internet, um aplicativo elenco com informações de atualização e versão, juntamente com as notas de lançamento no formato Markdown ou HTML. Esta biblioteca ajuda você a verificar uma atualização, mostrar ao usuário as notas de versão e oferecer baixar/instalar a nova versão do software.
Tipos de download de atualização suportados embutidos:
Consulte Upgradering.md para obter informações sobre as principais alterações da versão, atualizações, etc.
Netsparkle está disponível via Nuget. Para escolher um pacote Nuget para usar:
NetSparkleUpdater.SparkleUpdater package se você não se importa em ter uma interface de usuário embutida e pode gerenciar as coisas você mesmo| Pacote | Caso de uso | Liberar | Visualização | Downloads |
|---|---|---|---|---|
| NetsparkleUpDater.SparkleUpDater | Pacote principal; Use uma interface do usuário 100% personalizada ou nenhuma interface do usuário (nada embutido) | |||
| WinForms UI (.NET Framework) | Netsparkle com interface de interface do winforms embutida | |||
| WinForms UI (.NET 6+) | Netsparkle com interface de interface do winforms embutida | |||
| WPF UI (.NET Framework e .Net 6+) | Netsparkle com interface do usuário WPF embutida | |||
| Avalonia UI | Netsparkle com interface de usuário embutida | |||
| Ferramenta de gerador de elenco de aplicativos | Ferramenta CLI netsparkle-generate-appcast (incl. ED25519 HELHERAS) | |||
| Ferramenta DSA Helper | Ferramenta netsparkle-dsa CLI (DSA Helpers) |
Informações rápidas para instalações de ferramentas:
dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator ; Disponível como netsparkle-generate-appcast em sua linha de comando após a instalaçãodotnet tool install --global NetSparkleUpdater.Tools.DSAHelper ; Disponível como netsparkle-dsa em sua linha de comando após a instalação Um caminho típico de atualização de software para um software estereotipado pode ser assim:
dotnet publish )No momento, o NetsparkleUpdater não o ajuda com 1., 2. ou 4. "Por que não?", Você pode perguntar:
sudo por qualquer motivo, há um exemplo de fazer isso na amostra do MacOS Avalonia .Para criar seu arquivo de elenco de aplicativos, consulte a seção de fundição do aplicativo deste documento.
Estamos abertos a contribuições que podem facilitar o processo geral de instalação/atualização para o usuário. Por favor, arquive um problema primeiro com sua ideia antes de começar a trabalhar para que possamos falar sobre isso.
Por favor, observe os projetos de amostra neste repositório para amostras básicas e executáveis de uso !! Existem amostras sobre o uso de cada uma das UIs embutidas, bem como uma amostra "faça você mesmo na sua própria interface do usuário"!
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 formulário principal ou 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), um arquivo DMG (Linux), um arquivo .tar.gz (Linux) ou similar. Mais informações na seção de trabalho de como atualizações.netsparkle-generate-appcast --help para opções): netsparkle-generate-appcast -b binary/folder -p change/log/folder -u https://example.com/downloads -l https://example.com/downloads/changelogs.signature ou arquivos similares) para os locais apropriados em seu servidorSparkleUpdater.LogWriter para ver se há alguma informação útil de depuração que apareça no console! No seu arquivo de projeto, certifique -se de configurar algumas coisas para que a biblioteca possa ler nos detalhes pertinentes posteriormente. NOTA: Você pode usar seu próprio IAssemblyAccessor para carregar as informações da versão de outro lugar. No entanto, é fácil configurar as coisas no seu arquivo de projeto, e o NetsparkleUpDater pode ler isso em nativamente!
< 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: No .NET 8+, foi feita uma alteração no núcleo do .NET que faz com que o seu hash de cometer de código git/fonte seja incluído no número <Version> do seu aplicativo. Esse comportamento não pode ser evitado pelo NetsparkleUpDater no momento, à medida que confiamos no AssemblyInformationalVersionAttribute , e o comportamento desse atributo foi alterado. Seus usuários podem ser informados de que estão atualmente executando 1.0.0+commitHashHere pelo NetsparkleUpDater (e seu próprio aplicativo nativo!). Também recomendamos a adição das seguintes linhas ao seu arquivo de projeto (em um novo <PropertyGroup> ou em uma 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!No primeiro evento Application.idle, seu arquivo XML CAST do aplicativo será baixado, lido e comparado à versão atualmente em execução. Se tiver uma atualização de software dentro, o usuário será notificado com uma pequena notificação de brindes (se suportada pela interface do usuário e ativada) ou com uma caixa de diálogo de atualização contendo suas notas de versão. O usuário pode ignorar a atualização, pedir para ser lembrado posteriormente ou baixar/instalá -lo agora.
Se você deseja verificar se há uma atualização em segundo plano sem que o usuário veja nada, use
var updateInfo = _sparkle . CheckForUpdatesQuietly ( ) ;Se você deseja ter um item de menu para o usuário verificar se há atualizações para que o usuário possa ver a interface do usuário enquanto o Netsparkle procura atualizações, use
_sparkle . CheckForUpdatesAtUserRequest ( ) ;Se você tiver arquivos que precisam salvar, assine o evento PreparingToExit:
_sparkle . PreparingToExit += ( ( x , cancellable ) =>
{
// ask the user to save, whatever else is needed to close down gracefully
} ) ; Observe que, se você não usar um UIFactory , deverá usar os eventos CloseApplication ou CloseApplicationAsync para fechar seu aplicativo; Caso contrário, seu arquivo de atualização baixado nunca será executado/leitura! A única exceção a isso é se você deseja lidar com todos os aspectos da instalação do pacote de atualização.
O arquivo que inicia sua atualização baixada executável aguarda apenas 90 segundos antes de desistir! Certifique -se de que seu software feche dentro de 90 segundos de ClosetAplication/CloseApplicationAsync sendo chamado se você implementar esses eventos! Se você precisar de um evento que possa ser cancelado, como quando o usuário precisar ser perguntado se não há problema em fechar (por exemplo, salvar seu trabalho), use PreparingForExit ou PreparingToExitAsync .
IUIFactory ; Definir SparkleUpdater.UIFactory para utilizar uma instância do seu objeto.ICheckingForUpdates para sua interface do usuário que diz ao usuário que SparkleUpdater está verificando as atualizaçõesIDownloadProgress para sua interface do usuário que mostra ao usuário que uma atualização está sendo baixadaIUpdateAvailable para sua interface do usuário que mostra ao usuário que uma atualização está disponível junto com as notas de lançamentoIAppCastDataDownloader para configurar seus próprios métodos para baixar dados de elenco do aplicativo; SET SparkleUpdater.AppCastDataDownloader para utilizar uma instância do WebRequestAppCastDataDownloader objeto LocalFileAppCastDownloaderIAppCastFilter para fazer filtragem personalizada nos objetos AppCastItem em seu aplicativo baixado, por exemplo, para considerar apenas um determinado subconjunto de itens como atualizações válidas para o seu aplicativo; Defina AppCastHelper.AppCastFilter ( SparkleUpdater.AppCastHelper.AppCastFilter ) para utilizar uma instância do seu objeto. O Netsparkle inclui a classe ChannelAppCastFilter , que você pode usar para filtrar itens por um determinado canal de produto (por exemplo, alfa, beta) se o seu aplicativo utilizar esses recursos.IAppCastGenerator para controlar como os elenco do aplicativo são serializados e desserializados; Definir SparkleUpdater.AppCastGenerator para utilizar uma instância do seu objeto. O Netsparkle inclui duas implementações: XMLAppCastGenerator , para serialização/deserialização XML; e JsonAppCastGenerator , para serialização/deserialização JSON. A ferramenta CLI do gerador de elenco do aplicativo também pode gerar elenco de aplicativos XML e JSON.IAssemblyAccessor para controlar como a versão, os direitos autorais e outros detalhes do produto são carregados para o seu aplicativo; Definir Configuration.AssemblyAccessor ( SparkleUpdater.Configuration.AssemblyAccessor ) para utilizar uma instância do seu objeto. O Netsparkle contém uma implementação padrão, AssemblyDiagnosticsAccessor , que deve funcionar no caso geral de carregar dados de uma determinada montagem.ILogger e defina SparkleUpdater.LogWriter . Por padrão, a classe LogWriter é usada (que possui a propriedade LogWriterOutputMode para controlar se os logs são gravados para Console , Trace etc.)ISignatureVerifier para alterar como suas assinaturas para o aplicativo fundido, downloads etc. são tratadas; Definir SparkleUpdater.SignatureVerifier para utilizar uma instância do seu objeto.IUpdateDownloader para configurar seus próprios métodos para baixar e enviar progresso nos arquivos de atualização do aplicativo (por exemplo, instaladores) para um determinado item de elenco do aplicativo; Set SparkleUpdater.UpdateDownloader para utilizar uma instância do seu objeto. O Netsparkle inclui duas implementações por padrão: WebFileDownloader (padrão) para baixar arquivos do Web/Internet e LocalFileDownloader para copiar/"baixar" um arquivo de um determinado caminho. Configuration da subclasse para alterar como certas informações do NetSparkle são salvas e carregadas - por exemplo, informações de versão ignoradas. Esta classe é a que utiliza uma instância IAssemblyAccessor para salvar e carregar informações da versão, nome do produto, etc. Netsparkle contém três implementações: RegistryConfiguration , que salva e carrega informações no Registry do Windows (padrão no Windows); JSONConfiguration , que salva e carrega informações em um arquivo json (padrão no macOS/linux); e DefaultConfiguration , que não faz nada e serve como um retorno, caso JSONConfiguration não possa encontrar um local de arquivo válido para salvar e carregar dados. Para usar a instância da sua classe, defina SparkleUpdater.Configuration .RegistryConfiguration permite alterar rapidamente o caminho do registro onde os itens são salvos via BuildRegistryPathJSONConfiguration permite alterar rapidamente o caminho do arquivo em que os dados são salvos via GetSavePathAppCastHelper Se você deseja controle total sobre o processo de download e análise de download e análise do aplicativo. Observe que você provavelmente pode fazer tudo o que precisa fazer através das propriedades AppCastHelper (incluindo IAppCastFilter AppCastFilter ), mas a subclasse fornecerá controle absoluto e completo sobre todo o processo. Para usar a instância da sua classe, defina SparkleUpdater.AppCastHelper .ReleaseNotesGrabber para controlar o processo Notas de lançamento (e, portanto, exibir). Para usar uma instância da sua classe, defina UIFactory.ReleaseNotesGrabberOverride .WebFileDownloader se você não deseja implementar IUpdateDownloader e apenas deseja substituir uma função ou duas, como CreateHttpClient ou RetreiveDestinationFileNameAsync . Para usar uma instância da sua classe, defina SparkleUpdater.UpdateDownloader .WebRequestAppCastDataDownloader se você não deseja implementar IAppCastDataDownloader e apenas deseja substituir uma função ou duas como CreateHttpClient . Para usar uma instância da sua classe, defina SparkleUpdater.AppCastDataDownloader .LogWriter para implementar a função PrintMessage ; Como ILogger é uma interface bastante simples, você provavelmente pode implementar essa interface se suas necessidades forem complexas. Para usar uma instância da sua classe, defina SparkleUpdater.LogWriter .SparkleUpdater para implementar algumas funções relacionadas à instalação diferentes, incluindo:GetWindowsInstallerCommandGetInstallerCommandRunDownloadedInstallerGetDownloadPathForAppCastItemUIFactory se você não deseja implementar a totalidade da interface IUIFactory e apenas deseja configurar uma função ou duas. Para usar uma instância da sua classe, defina SparkleUpdater.UIFactory . IAppCastFilter Você pode alterar a forma como o seu aplicativo elenco é filtrado através da propriedade AppCastHelper.AppCastFilter (através da interface IAppCastFilter ). Isso permite alterar quais itens são disponibilizados para seus usuários finais.
O Netsparkle contém uma implementação interna IAppCastFilter para filtragem baseada em canal chamada ChannelAppCastFilter . Para alguns exemplos sobre como usar essa classe, consulte os testes de unidade aqui. Basicamente, defina a List<string> ChannelSearchNames para os canais pelos quais você deseja filtrar. Se você deseja manter itens sem informações do canal (por exemplo, 1.2.3 ), defina KeepItemsWithNoChannelInfo como true .
Para realmente definir canais em seu aplicativo itens de elenco / no seu aplicativo, ele fundam, use a propriedade --channel da ferramenta CLI fundido do aplicativo ou defina a propriedade <Version> do seu arquivo de projeto para a versão semver compatível com Semver (por exemplo, <Version>1.0.2-beta1</Version> >) e o aplicativo CLI CLI Ou, se você estiver construindo seu aplicativo moldado manualmente, defina a propriedade <sparkle:channel>YourChannelHere</sparkle:channel> em sua <item> (ou, se estiver usando o JSON, a propriedade channel ).
NetsparkleUpDater não precisa ser usado com uma interface do usuário. Você pode fazer tudo sozinho ou até mesmo que a biblioteca execute sua atualização baixada automaticamente, configurando o SparkleUpdater.UserInteractionMode = UserInteractionMode.DownloadAndInstall . Este repositório tem uma amostra sobre como fazer as coisas sem nenhuma interface do usuário pré-criada no SRC/Netsparkle.samples.HandleEventsyingselle.
Se você deseja uma interface do usuário, oferecemos UIs pré-construídas em diferentes pacotes Nuget com um pequeno número de opções personalizáveis para WinForms, WPF e Avalonia. As UIs são acionadas por meio de uma implementação IUIFactory , chamada UIFactory em cada uma das opções internas. A maioria dos métodos no UIFactory pode ser substituída se você quiser ajustar o comportamento, e o ProcessWindowAfterInit permite personalizar cada janela após a fabricação.
Se você deseja rolar completamente sua própria interface do usuário, basta implementar a interface IUIFactory com qualquer biblioteca de interface do usuário que você deseja usar. Você pode copiar ou reutilizar modelos de visualização, código etc. das opções pré -construídas do NetSparkleUpDater e copiar o código de coleta deste repositório para o seu é provavelmente uma maneira boa e rápida de iniciar. Não se esqueça de definir a propriedade SparkleUpdater.UIFactory com uma instância da sua implementação IUIFactory !
Observação: o Netsparkle basicamente não faz tentativas de se preocupar com a Threading (por exemplo, chamando para o thread principal), exceto o loop de fundo que chama para o thread principal que iniciou a instância SparkleUpdater . Em outras palavras, de um modo geral, o Netsparkle fará tudo no tópico que originalmente criou a instância SparkleUpdater . Para a maioria dos aplicativos, isso ficará bem, pois eles estão apenas usando o tópico principal da interface do usuário. Em caso de dúvida, para suas próprias necessidades de interface do usuário, verifique InvokeRequired no WinForms e no WPF/Avalonia, marecham as coisas do thread da interface do usuário (a menos que você esteja usando a ligação de dados, nesse caso, é tratado para você!).
Passando sua própria implementação IUIFactory que inicia o Windows/Things em novos threads no SparkleUpdater não é uma configuração suportada. Se você deseja executar sua própria interface do usuário em vários threads (por exemplo, para que o WinForms não tenha fechado as janelas do NetsparkleUpdater quando o formulário principal fechar), faça -o usando os eventos do SparkleUpdater e não o UIFactory ; Consulte também a amostra SRC/Netsparkle.samples.forms.multithread para obter um exemplo prático de como fazer isso.
O aplicativo elenco é apenas um arquivo XML ou JSON. Ele contém campos como o título e a descrição do seu produto, bem como uma definição por versão do seu software.
Recomendamos fortemente que você use a ferramenta Netsparkle-Generate-Appcast para criar (e posteriormente recriar/atualizar) o arquivo, pois pode ajudar a cuidar de todos os requisitos de assinatura para você.
dotnet tool install --global NetSparkleUpdater.Tools.AppCastGeneratornetsparkle-generate-appcast . Você pode usar netsparkle-generate-appcast --help para ver uma lista completa de opções para esta ferramenta. Por padrão, o Netsparkle usa o aplicativo XML compatível com Sparkle na maior parte . O Netsparkle usa sparkle:signature em vez de sparkle:edSignature para que você possa escolher como assinar seus arquivos/aplicativos fundidos. (Se você deseja usar sparkle:edSignature , Pass --use-ed25519-signature-attribute para o gerador de elenco do aplicativo.) Observe que o Netsparkle é compatível e usa as assinaturas ED25519 por padrão, mas a estrutura pode lidar com uma versão diferente da classe ISignatureVerifier para verificar diferentes tipos de tipos de imaduza.
Aqui está um amostra de aplicativo 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 > O Netsparkle lê as tags <item> para determinar se as atualizações estão disponíveis.
As tags importantes em cada <item> são:
<description><sparkle:releaseNotesLink> .<sparkle:releaseNotesLink><description> estiver presente, ela será usada.sparkle:signature , opcional: a assinatura DSA/ED25519 do documento; O Netsparkle não verifica essa assinatura para você, a menos que você defina ReleaseNotesGrabber.ChecksReleaseNotesSignature como true , mas você pode verificar manualmente as assinaturas de Changelog se você gosta ou definir ReleaseNotesGrabber.ChecksReleaseNotesSignature = true na sua UI.<pubDate>sparkle:channel : canal para este aplicativo elenco de item, por exemplo, beta (não é necessário) - aceita apenas 1 canal<enclosure>url : URL do arquivo de atualizaçãosparkle:version : Número da versão legível por máquina desta atualizaçãolength , opcional: (não validado) Tamanho do arquivo de atualização em bytestype : ignoradosparkle:signature : DSA/ED25519 Assinatura do arquivo de atualizaçãosparkle:criticalUpdate , opcional: se igual a true ou 1 , a interface do usuário indicará que esta é uma atualização críticasparkle:os : Sistema operacional para o item de elenco do aplicativo. Padrões para Windows se não forem fornecidos. Para Windows, use "Win" ou "Windows"; Para MacOS, use "macOS" ou "OSX"; Para Linux, use "Linux". Por padrão, você precisa de 2 assinaturas ( SecurityMode.Strict ):
sparkle:signature="..." )NOTA: A ferramenta de gerador de elenco do aplicativo cria essas duas assinaturas para você quando recria o arquivo appcast.xml.
Você pode gerar assinaturas ED25519 usando a ferramenta AppCastGenerator (a partir deste pacote NUGET ou no código -fonte aqui). Esta ferramenta requer o tempo de execução .Net 6, 7, 8 ou 9 da área de trabalho para ser instalado. Consulte as seções abaixo para obter opções e exemplos sobre a geração das teclas ED25519 e para usá -las ao criar um aplicativo fundido.
AppCastGenerator (deste pacote NUGET ou no código -fonte aqui) para criar facilmente o seu arquivo de elenco do aplicativo. As opções disponíveis estão descritas abaixo. Você pode instalá -lo na sua dotnet tool install --global NetSparkleUpdater.Tools.AppCastGenerator .string.Format ou similar é uma coisa maravilhosa).Se você quiser usar um aplicativo JSON em vez de XML:
--output-type json ao gerar seu arquivo de elenco de aplicativos através do gerador de fundição de aplicativosSparkleUpdater.AppCastGenerator para new JsonAppCastGenerator(mySparkleUpdater.LogWriter) .JsonAppCastGenerator.HumanReadableOutput como false .Faltando alguma opção que você gostaria de ver? Arquive um problema neste repositório ou adicione você mesmo e envie -nos uma solicitação de tração!
--show-examples : Imprima exemplos de uso no console.--help : mostre todas as opções e suas descrições. -a / --appcast-output-directory : diretório para gravar o arquivo de saída appcast.xml . Exemplo de uso: -a ./MyAppCastOutput-e / --ext : Ao procurar arquivos para adicionar ao aplicativo fundido, use a (s) extensão (s) fornecida (s) ao procurar arquivos. Padrões para exe . Exemplo de uso: -e exe,msi-b / --binaries : caminho do arquivo para o diretório que deve ser pesquisado ao procurar arquivos a serem adicionados ao aplicativo fundido. Padrão para . . Exemplo de uso: -b my/build/directory-r / --search-binary-subdirectories : verdadeira pesquisar no diretório binário recursivamente por binários; Falso para pesquisar apenas o diretório principal. Padrões para false . Exemplo de uso: -r .--single-file : arquivo único a ser adicionado ao aplicativo fundido-se definido, --binaries , --ext , etc. são todos ignorados. É útil usar se o seu arquivo de saída não tiver extensão (por exemplo, é um executável do UNIX). Exemplo Use: --single-file path/to/my/file-f / --file-extract-version : Extrair ou não a versão do arquivo do nome do arquivo em vez do arquivo (por exemplo, DLL). Padrões para false . Use quando seus arquivos que serão baixados pelo NetsparkleUpDater terão o número da versão no nome do arquivo, por exemplo, "meu aplicativo 1.3.2-alpha1.exe". Observe que isso pesquisa apenas os quatro últimos itens/pastas de diretório. Exemplo de uso: -f true--file-version : Use para definir a versão para um binário entrar em um aplicativo elenco. Observe que esta versão só pode ser definida uma vez, portanto, ao gerar um aplicativo fundido, certifique -se de que você: a) tenha apenas um binário no seu aplicativo fundido | B) Utilize o parâmetro --reparse-existing os itens antigos. Se o gerador encontrar 2 binários sem nenhuma versão conhecida e --file-version estiver definido, será emitido um erro. Exemplo Use: --file-version 1.3.2-o / --os : sistema operacional ao qual os itens de elenco do aplicativo pertencem. A string deve incluir um dos seguintes: windows , mac , linux . Padrões no windows . Exemplo de uso: -o macos-arm64 ; -o windows-x64--description-tag : texto a ser colocado no aplicativo Cast Descrição Tag/Informações. Padrões para "Alterações mais recentes com links para atualizações". Exemplo Use: --description-tag "Hello I am a Cool App"--link-tag : texto a ser colocado na tag/informação do link de elenco do aplicativo. Deve ser o seu aplicativo de download de download do aplicativo se você usar isso. Exemplo de uso: --link-tag https://mysite.com/coolapp/appcast.xml-u / --base-url : Parte inicial do URL para usar para downloads. O nome do arquivo que será baixado será colocado após esta parte do URL. Exemplo de uso: -u https://myawesomecompany.com/downloads-l / --change-log-url : parte inicial do URL para usar para seus arquivos de log de alterações. O arquivo de log de alterações que será baixado será colocado após esta parte do URL. Se essa opção não for especificada, os dados do log de alterações serão colocados no próprio aplicativo. Exemplo de uso: -l https://myawesomecompany.com/changes-p / --change-log-path : caminho para os arquivos de log de alterações para o seu software. Espera -se que estes estejam em formato de marcação com uma extensão de .md . O nome do arquivo dos arquivos de log de alterações deve conter a versão do software, por exemplo, 1.3.2.md Exemplo de uso: -p path/to/change/logs . (Nota: o gerador também tentará encontrar troncos de alteração cujos nomes de arquivos são formatados como assim: MyApp 1.3.2.md )--change-log-name-prefix : prefixo para alterações nomes de arquivos de log. Por padrão, o gerador procura nomes de arquivos com o formato "[versão] .md". Se você definir este parâmetro como (por exemplo) "meu log de alterações de aplicativo", ele procurará nomes de arquivos com o formato "Meu aplicativo Alterar log [versão] .md" e "[versão] .md".-n / --product-name : nome do produto para o seu software. Usado ao definir o título para o seu aplicativo elenco e seus itens. Padrões de Application . Exemplo de uso: -n "My Awesome App"-x / --url-prefix-version : Adicione o número da versão como um prefixo ao nome do arquivo para o URL de download. Padrões para false. Por exemplo, se --base-url for www.example.com/downloads , sua versão é 1.4.2 e seu nome de aplicativo é MyApp.exe , seu URL de download se tornará www.example.com/downloads/1.4.2/MyApp.exe . Exemplo de uso: -x true .--key-path : Path to NetSparkle_Ed25519.priv e NetSparkle_Ed25519.pub Arquivos, que são suas chaves privadas e públicas ED25519 para as atualizações de seu software, respectivamente. Exemplo de uso: --key-path my/path/to/keysSPARKLE_PRIVATE_KEY e SPARKLE_PUBLIC_KEY antes de executar generate_appcast . A ferramenta prioriza as teclas de ambiente sobre as teclas sentadas no disco!--signature-file-extension : Extensão (sem . ) Para usar para o arquivo de assinatura de elenco do aplicativo. Padrões de signature . Exemplo Use: --signature-file-extension txt .--output-file-name : Nome do arquivo de saída para o aplicativo fundido com o . ou a extensão. A extensão é controlada por ser uma saída XML ou JSON e não é configurável. Padrões para 'Appcast'. Obviamente, você sempre pode mudar isso mais tarde, depois que o elenco do aplicativo foi gerado; Esta opção é apenas para conveniência. Exemplo Use: --output-file-name super_app_download_info .--use-ed25519-signature-attribute : Se a saída True e a saída XML, o atributo de assinatura de saída no XML será edSignature em vez de signature para corresponder à biblioteca Sparkle original. Nenhum efeito no JSON aplicativo elenco.--file-version : Use para definir a versão para um binário entrar em um aplicativo elenco. Observe que esta versão só pode ser definida uma vez, portanto, ao gerar um aplicativo fundido, certifique -se de que você: a) tenha apenas um binário no seu aplicativo fundido | B) Utilize o parâmetro --reparse-existing os itens antigos. Se o gerador encontrar 2 binários sem nenhuma versão conhecida e --file-version estiver definido, será emitido um erro.--critical-versions : Lista de versões separada por vírgula para marcar como crítica no elenco de aplicativos. Deve corresponder exatamente ao texto da versão. Por exemplo, "1.0.2,1.2.3.1".--reparse-existing : Renuse um aplicativo existente, em vez de substituí-lo e criá-lo de novo. Spips as versões já no aplicativo elenco; portanto, se você implantar um novo binário com a mesma versão, precisará editar manualmente seu aplicativo elenco para remover a lista antiga da versão que você está re-implantando. Exemplo de uso: --reparse-existing true--overwrite-old-items : faz com que os itens de elenco do aplicativo sejam reescritos no aplicativo fundido se o binário em disco com o mesmo número de versão for encontrado. Em outras palavras, se 1.0.1 já estiver no aplicativo elenco (seja de recuperação ou de outro binário), e outro 1.0.1 for encontrado no disco, os dados 1.0.1 no aplicativo fundido serão reescritos com base no binário encontrado. Observe que isso significa que, se você tiver várias versões 1.0.1 no disco (o que você não deve fazer ...), o último encontrado será o do seu aplicativo elenco! Exemplo de uso: --overwrite-old-items--human-readable : se verdadeiro, torna o arquivo de saída do aplicativo de saída Legable Human (linhas de notícias, recuos). Exemplo de uso: --human-readable true--channel : Nome do canal de liberação para quaisquer itens adicionados ao aplicativo fundido. Deve ser um único 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.
Não. 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.)
Sim. 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.
Sim!
--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.
Sim.
Sim.
Sim. 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.
Sim. 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.
Sim. 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.Sim! 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! Obrigado!! :) 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: