André Alves de Lima

Talking about Software Development and more…

Como atualizar aplicações .NET automaticamente?

Um grande desafio que temos ao desenvolvermos aplicações desktop é a questão da atualização para novas versões. Diferentemente de aplicações web, onde o usuário sempre receberá a versão mais atual que estiver disponibilizada no servidor, com as aplicações desktop nós temos que implementar essa atualização de forma manual. Para isso, nós temos à nossa disposição algumas ferramentas que nos ajudarão a atualizar as nossas aplicações .NET automaticamente quando uma nova versão estiver disponível. No artigo de hoje eu vou mostrar para você 3 ferramentas que implementam essa funcionalidade.

Aplicação de exemplo

Você pode utilizar qualquer aplicação desktop para testar as funcionalidades que serão apresentadas neste artigo. Isso quer dizer que o seu projeto pode ser do tipo Console Application, Windows Forms ou WPF, independente da linguagem (C# ou VB.NET).

Para simplificar as coisas, a aplicação que testaremos no artigo será do tipo Console Application. Ela será uma aplicação extremamente simples, que só mostra o nome e a versão do assembly no console:

        // C#
        static void Main(string[] args)
        {
            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
            var titleAttribute = assembly.GetCustomAttributes(typeof(System.Reflection.AssemblyTitleAttribute), false).FirstOrDefault() as System.Reflection.AssemblyTitleAttribute;
            var title = titleAttribute?.Title;
            var version = assembly.GetName().Version.ToString();
            Console.WriteLine(string.Format("Assembly Title: {0}", title));
            Console.WriteLine(string.Format("Assembly Version: {0}", version));
            Console.ReadLine();
        }
    ' VB.NET
    Sub Main()
        Dim Assembly = System.Reflection.Assembly.GetExecutingAssembly()
        Dim TitleAttribute = TryCast(Assembly.GetCustomAttributes(GetType(System.Reflection.AssemblyTitleAttribute), False).FirstOrDefault(), System.Reflection.AssemblyTitleAttribute)
        Dim Title = If(TitleAttribute IsNot Nothing, TitleAttribute.Title, String.Empty)
        Dim Version = Assembly.GetName().Version.ToString()
        Console.WriteLine(String.Format("Assembly Title: {0}", Title))
        Console.WriteLine(String.Format("Assembly Version: {0}", Version))
        Console.ReadLine()
    End Sub

Você consegue encontrar as informações de versão do assembly nas propriedades do projeto, aba “Application“, botão “Assembly Information“:

A propósito, os números de versão do assembly e do arquivo são informações extremamente importantes quando trabalhamos com instaladores e atualizadores, uma vez que ela pode ser a base da decisão se uma atualização está disponível ou não. Caso você não saiba, eu já publiquei um artigo uns tempos atrás mostrando como gerenciar números de versão em projetos .NET. O código apresentado acima é uma versão simplificada do código elaborado no artigo sobre números de versão.

Opção 1: ClickOnce

O ClickOnce é a ferramenta da própria Microsoft que implementa a funcionalidade de instalação e atualização de aplicações desktop. Ela está disponível no Visual Studio desde a versão 2005, quando o .NET Framework 2.0 foi lançado. Todas as opções do ClickOnce estão disponíveis nas propriedades do projeto, mais especificamente na aba “Publish“:

Nota: se a sua solução tiver mais de um projeto, você terá que fazer as configurações no projeto que é o “entry point” da sua aplicação, ou seja, no executável.

Dentro da aba “Publish“, nós conseguiremos fazer algumas configurações mais específicas através destes quatro botões:

No botão “Application Files“, nós podemos selecionar quais serão os arquivos que deverão ser copiados para a pasta de instalação do aplicativo. O Visual Studio costuma fazer um excelente trabalho detectando quais arquivos devem ser incluídos ou não (utilizando as referências dos projetos, itens que estão marcados como “Copy to output directory“, etc). Porém, caso você tenha algum arquivo adicional (como um arquivo de backup do SQL Server que você restaurará automaticamente na primeira execução, como demonstrei neste outro artigo), você terá que adicioná-lo nessa janela.

Já na janela de “Prerequisites” nós conseguimos, como o próprio nome já diz, selecionar pré-requisitos adicionais que serão instalados juntamente com a aplicação. Por exemplo, você pode selecionar o SQL Server Express (ou LocalDB) como pré-requisito, dessa forma uma instância será instalada e habilitada automaticamente quando o usuário fizer a instalação da nossa aplicação.

Na parte de “Updates” nós temos uma configuração muito importante, que é a questão de atualizações da nossa aplicação. A grande vantagem que temos ao fazer a instalação pelo ClickOnce é justamente a opção de manter a aplicação atualizada automaticamente:

Como você pode ver, nessa janela nós conseguimos ativar ou desativar as atualizações automáticas. Além disso, nós podemos definir se o ClickOnce fará a checagem de atualizações antes ou depois da inicialização da aplicação, além de uma versão mínima e um endereço customizado onde as atualizações serão disponibilizadas.

Por fim, temos um último botão chamado “Options“, onde encontraremos configurações gerais da publicação. Por exemplo, se quisermos adicionar a criação de um ícone no desktop para a nossa aplicação, nós temos que marcar a seguinte opção:

Nessa mesma aba “Publish“, nós temos o número da versão de publicação:

Não confunda o número da versão do assembly / arquivo (que expliquei anteriormente) com a versão da publicação. Esses números são independentes e podem ter versões completamente distintas para cada um deles. Caso você queira acessar o número da versão da publicação em tempo de execução, você terá que utilizar as informações disponíveis na classe System.Deployment.Application.ApplicationDeployment.CurrentDeployment, conforme demonstrado nesta thread do StackOverflow.

Uma vez realizadas as configurações básicas, nós vamos utilizar o “Publish Wizard” para especificarmos os locais de publicação. O ClickOnce pode funcionar simplesmente como um instalador comum (sem checagem de atualizações), porém, caso você só queira criar um instalador sem suporte a atualizações, eu recomendo que você utilize uma outra ferramenta de instalador mais robusta (como o InnoSetup ou até mesmo os projetos de instalador do Visual Studio, ambos apresentados neste outro artigo que eu publiquei uns tempos atrás).

Para trabalhar com atualizações automáticas no ClickOnce, nós teremos que disponibilizar as atualizações em um site no IIS ou em um caminho na rede. Seria excelente se o ClickOnce permitisse a publicação em um caminho em disco, uma vez que isso facilitaria bastante os testes, mas infelizmente isso não é possível. Se tentarmos especificar um caminho em disco para a atualização, nós receberemos uns erros estranhos, como estes:

Porém, uma gambiarra que podemos empregar para testarmos o deployment local é utilizarmos um caminho no formato UNC em conjunto com o compartilhamento de disco padrão do Windows (C$, D$, etc). No tutorial deste artigo nós trabalharemos com essa alternativa.

Na primeira página do “Publish Wizard“, nós temos que indicar o caminho onde a aplicação será publicada. Se estivéssemos fazendo um deployment “de verdade“, nós provavelmente indicaríamos nessa etapa o caminho do FTP (ou caminho da rede) onde a aplicação está publicada no IIS. Porém, para testarmos o deployment local, nós deixaremos o caminho como “publish\” (que é o padrão):

Em seguida, na próxima etapa do assistente nós temos que indicar o local por onde o usuário vai instalar a nossa aplicação. Uma opção é através de CD (não recomendado – como já mencionei anteriormente, vale muito mais a pena utilizar um instalador mais robusto para esse cenário). Caso estivéssemos publicando a nossa aplicação no IIS, nesta etapa nós teríamos que indicar a URL pública do IIS (ou da intranet, se a aplicação fosse interna). Porém, como nós estamos tentando testar um deployment local, nós indicaremos um caminho UNC apontando para a mesma pasta “publish“:

Nota: no meu caso, o caminho UNC ficou assim: “\\192.168.178.20\C$\Users\jamje\Documents\Visual Studio 2015\Projects\AtualizadorAplicacao\AtualizadorAplicacao\publish\”. Obviamente, no seu caso você precisará substituir o IP e o caminho de forma que eles correspondam à pasta “publish” do seu projeto.

Por fim, clique em “Finish” para concluir o assistente. Ao fazer isso, uma primeira publicação será efetuada dentro da pasta indicada nas configurações. Para instalar a aplicação, basta executarmos o arquivo “setup“:

Uma vez instalada a aplicação, ela buscará atualizações na URL indicada no processo de deployment sempre que ela for iniciada e, quando uma nova versão estiver disponível, o usuário poderá escolher se quer instalar ou não a versão atualizada:

E com isso o nosso instalador / atualizador feito com o ClickOnce está pronto para ser instalado em um servidor de verdade (no IIS). Se você quiser ver como fazer a publicação com o ClickOnce no Azure, veja este excelente vídeo do André Secco onde ele mostra um passo-a-passo.

Desafios do ClickOnce

Como você pode ver, o ClickOnce é muito simples de ser configurado. Porém, ele não é somente mil maravilhas. Existem diversos desafios que temos que enfrentar ao utilizarmos o ClickOnce como ferramenta de deployment dos nossos aplicativos.

– Instalação somente para um usuário

O primeiro problema é que a instalação é feita somente para o usuário que está executando o instalador. Ou seja, não dá para instalar a aplicação para todos os usuários (opção bem conhecida em diversas ferramentas de instaladores). Outro problema é que, como o setup roda no contexto do usuário, não é possível executá-lo como administrador. Isso acaba limitando as tarefas que podem ser feitas durante a instalação. Você quer rodar um arquivo batch que precisa de permissão de administrador durante a instalação? Pode esquecer, com o ClickOnce não é possível.

– Local da instalação não customizável

Esse é o ponto que mais me deixa irritado na instalação com o ClickOnce. O usuário não pode escolher o local onde a aplicação será instalada. E o pior de tudo é que o local de aplicação é um lugar bem nas entranhas no sistema de arquivos (dentro de alguma subpasta de “C:\Users\NomeDoUsuario\AppData\Local\Apps\2.0“, local onde todas as aplicações ClickOnce são instaladas). Portanto, se a sua aplicação precisa obrigatoriamente estar rodando em uma pasta específica, você terá problemas com o ClickOnce.

– UI não customizável

Não é possível customizar a experiência de instalação do ClickOnce. O assistente de instalação é engessado e a única coisa que você consegue alterar é o idioma.

– Certificados necessários para não cair no Smart Screen

Se você tentar instalar e rodar uma aplicação distribuída com o ClickOnce no Windows 8 ou superior, você receberá uma mensagem do Smart Screen, que dirá que a aplicação que você está tentando instalar / rodar provavelmente não é confiável:

Isso acontece porque o Smart Screen só reconhece como “confiáveis” aplicações distribuídas com o ClickOnce que estejam assinadas por um certificado reconhecido. Ou seja, se você quiser remover esse anúncio irritante do Smart Screen no Windows 8 ou Windows 10, você terá que comprar um certificado para assinar a sua aplicação.

Opção 2: NAppUpdate

Para a nossa sorte, o ClickOnce não é a única ferramenta que podemos utilizar para implementarmos atualizações automáticas nas nossas aplicações. Existem outras ferramentas gratuitas (e open source) que implementam esse tipo de funcionalidade. A primeira ferramenta que eu quero mostrar além do ClickOnce é a NAppUpdate.

O NAppUpdate nada mais é que uma biblioteca que implementa a funcionalidade de atualização automática para aplicações .NET. Ela é uma biblioteca open source e você encontra todo o seu código fonte diretamente no GitHub.

Como o NAppUpdate está disponível no NuGet, para começarmos a utilizá-lo na nossa aplicação, basta adicionarmos uma referência:

Uma vez adicionada a referência, nós podemos utilizar as classes do NAppUpdate, que ficam dentro do namespace “NAppUpdate.Framework“. Porém, antes de codificarmos qualquer coisa com o NAppUpdate, vamos entender como é que ele funciona.

Primeiramente, o NAppUpdate não é um instalador, mas sim, somente um atualizador de aplicações. Isso quer dizer que a primeira versão da sua aplicação deverá ser distribuída através de um instalador convencional (como eu mostrei neste outro artigo). Uma vez instalada a aplicação no computador do cliente, nós podemos utilizar o poder do NAppUpdate para checarmos por atualizações.

A ideia do NAppUpdate é que nós teremos um arquivo de manifesto em algum lugar acessível (em um servidor web ou FTP, por exemplo). Esse arquivo de manifesto é um XML contendo tarefas que deverão ser executadas quando a aplicação for atualizada. Até o momento, existem dois tipos de tarefas: FileUpdateTask e RegistryTask, que servem para atualizar um arquivo ou uma entrada no registro, respectivamente.

Cada tarefa pode ter condições, que indicarão se elas serão ou não executadas, dependendo da versão que o usuário estiver rodando. Por exemplo, nós podemos configurar uma ação que substituirá o executável da nossa aplicação caso a versão instalada no computador do usuário seja menor que um certo número. No exemplo de manifesto abaixo, veja como podemos configurar o NAppUpdate de forma que ele atualize o executável da aplicação (AtualizadorAplicacao.exe) caso o arquivo no computador do usuário tenha uma versão menor do que “1.0.1.0“:

<?xml version="1.0" encoding="utf-8"?>
<Feed>
  <Tasks>
    <FileUpdateTask hotswap="false" updateTo="file://d:\tmp\update\AtualizadorAplicacao.exe" localPath="AtualizadorAplicacao.exe">
      <Description>Descricao da nova versao.</Description>
      <Conditions>
        <FileVersionCondition what="below" version="1.0.1.0" />
      </Conditions>
    </FileUpdateTask>
  </Tasks>
</Feed>

Vamos analisar com calma o conteúdo desse XML. Primeiramente, temos uma “FileUploadTask” com a propriedade “hotswap” definida como “false“. O “hotswap” indica se o arquivo pode ser substituído com a aplicação rodando ou não. Como nós estamos atualizando o próprio executável da aplicação, ele obviamente não poderá ser substituído com a aplicação em execução, então temos que definir “hotswap” como “false“. Caso você tente deixa-lo como “true“, o NAppUpdate não conseguirá fazer a atualização e retornará um erro parecido com este, dizendo que o arquivo está bloqueado:

Em seguida, temos o atributo “updateTo“, que definirá o caminho da versão mais atualizada do arquivo. No exemplo acima, estou utilizando um endereço que aponta para um arquivo em disco. Obviamente, em um deployment de verdade, o valor deverá ser um endereço acessível pela internet (ou intranet caso a aplicação seja interna). O NAppUpdate não verificará se o arquivo existe antes de tentar baixa-lo. Ou seja, se ele não encontrar o arquivo no caminho especificado, uma exceção será lançada:

O próximo atributo “localPath” corresponde ao caminho relativo do arquivo que será atualizado, tomando como base o diretório onde a aplicação está instalada. Se você quiser atualizar um arquivo que esteja em outra pasta, basta indicar o caminho completo nesse atributo.

Dentro da tarefa de atualização do arquivo, nós temos a condição que a atualização só deverá ser feita caso a versão atual no computador do usuário seja menor do que “1.0.1.0“. Aqui vale a pena mencionar que o NAppUpdate trabalha com o número de versão do arquivo, e não do assembly, portanto, tome cuidado com esse detalhe.

A implementação das outras opções de condições pode ser encontrada neste link. A condição “FileChecksumCondition” pode ser utilizada para atualizar um arquivo caso o seu check-sum corresponda a um valor específico (mais informações sobre check-sum MD5 e SHA neste meu outro artigo). Além disso, podemos utilizar também a “FileDateCondition” para atualizar um arquivo caso ele seja mais velho do que uma data específica ou a “FileSizeCondition“, que faz o mesmo considerando o tamanho do arquivo. Temos também a “FileExistsCondition“, que simplesmente atualiza o arquivo caso ele exista no computador do cliente e a “OSCondition“, para checar se o sistema operacional é 32 bits ou 64 bits. Por fim, com a “BooleanCondition” nós conseguimos agrupar várias condições em uma só.

Agora que já vimos um pouco da estrutura do arquivo de manifesto do NAppUpdate, vamos ver como é que fica o código para atualizarmos a nossa aplicação. Primeiramente, o NAppUpdate trabalha com o conceito de “singleton“. Isso quer dizer que somente uma instância dele será criada de cada vez. Ou melhor, no caso do NAppUpdate, essa instância já está criada e pode ser acessada através da propriedade “NAppUpdate.Framework.UpdateManager.Instance“.

Dentro dessa instância, a primeira coisa que temos que configurar é o caminho do arquivo de manifesto. Fazemos isso através da propriedade “UpdateSource“. Em seguida, nós chamamos o método “CheckForUpdates” e, caso alguma atualização esteja disponível (propriedade “UpdatesAvailable“), nós chamamos os métodos “PrepareUpdate” (para baixar a atualização) e “ApplyUpdate” (para instalar a atualização). Uma das sobrecargas do método “ApplyUpdate” recebe um valor booleano, indicando se a aplicação deve ser reiniciada após a atualização ou não:

            // C#
            var updateManager = NAppUpdate.Framework.UpdateManager.Instance;
            updateManager.UpdateSource = new NAppUpdate.Framework.Sources.SimpleWebSource(@"file://d:\tmp\nappupdate.xml");
            updateManager.CheckForUpdates();
            if (updateManager.UpdatesAvailable > 0)
            {
                updateManager.PrepareUpdates();
                updateManager.ApplyUpdates(true);
            }
        ' VB.NET
        Dim UpdateManager = NAppUpdate.Framework.UpdateManager.Instance
        UpdateManager.UpdateSource = New NAppUpdate.Framework.Sources.SimpleWebSource("file://d:\tmp\nappupdate.xml")
        UpdateManager.CheckForUpdates()
        If UpdateManager.UpdatesAvailable > 0 Then
            UpdateManager.PrepareUpdates()
            UpdateManager.ApplyUpdates(True)
        End If

Um detalhe importante com o NAppUpdate é que ele disparará uma exceção se o caminho para o arquivo de manifesto não estiver disponível:

Dito isso, é recomendado que você envolva todo o código relacionado ao NAppUpdate em um bloco try-catch, dessa forma nós evitamos crashes da aplicação. Afinal de contas, não vai cair nada bem se a nossa aplicação estiver crashando na hora de procurar por atualizações.

Enfim, se recompilarmos o projeto e tentarmos executá-lo, o NAppUpdate indicará que uma atualização está disponível (porque nós configuramos a versão do arquivo como “1.0.0.0” nas propriedades do projeto). Em seguida, ele baixará a nova versão do endereço indicado, fechará a aplicação para fazer a substituição do arquivo, porém, ele não conseguirá carregar a aplicação novamente caso estejamos executando através do Visual Studio:

Isso acontece porque, quando iniciamos o modo de debug do Visual Studio, ele não executa diretamente a aplicação, mas sim, uma outra cópia do nosso executável (com final “vshost.exe“). Para contornarmos esse problema, nós temos que executar a aplicação sem estar em modo debug (ou podemos executar a aplicação diretamente pelo Windows Explorer).

Para evitarmos problemas de loop infinito com o NAppUpdate e para detectarmos se a atualização foi realizada com sucesso na próxima execução da aplicação, nós temos que chamar o método “ReinstateIfRestarted” (nos casos em que a nossa aplicação tenha que ser reiniciada ao aplicar a atualização). Ao fazermos isso, nós receberemos um outro erro:

Esse erro acontece porque, uma vez aplicado o update, nós não podemos chamar o método “CheckForUpdates” novamente na próxima execução da aplicação. O código correto nesse caso inclui a verificação do estado do “UpdateManager“. Nós só seguiremos com a checagem das atualizações caso o código ainda não tenha sido executado. Veja como fica o código final para implementarmos a checagem e aplicação de atualizações automáticas no nosso aplicativo:

            // C#
            var updateManager = NAppUpdate.Framework.UpdateManager.Instance;
            updateManager.UpdateSource = new NAppUpdate.Framework.Sources.SimpleWebSource(@"file://d:\tmp\nappupdate.xml");
            updateManager.ReinstateIfRestarted();
            if (updateManager.State == NAppUpdate.Framework.UpdateManager.UpdateProcessState.NotChecked)
            {
                updateManager.CheckForUpdates();
                if (updateManager.UpdatesAvailable > 0)
                {
                    updateManager.PrepareUpdates();
                    updateManager.ApplyUpdates(true);
                }
            }
        ' VB.NET
        Dim UpdateManager = NAppUpdate.Framework.UpdateManager.Instance
        UpdateManager.UpdateSource = New NAppUpdate.Framework.Sources.SimpleWebSource("file://d:\tmp\nappupdate.xml")
        UpdateManager.ReinstateIfRestarted()
        If UpdateManager.State = NAppUpdate.Framework.UpdateManager.UpdateProcessState.NotChecked Then
            UpdateManager.CheckForUpdates()
            If UpdateManager.UpdatesAvailable > 0 Then
                UpdateManager.PrepareUpdates()
                UpdateManager.ApplyUpdates(True)
            End If
        End If

É claro que dessa forma nós não estamos dando a opção de o usuário instalar ou não a atualização (nós estamos fazendo de maneira “invisível“). Caso você queira dar essa opção para os seus usuários, você terá que implementar a interface por conta própria.

E com isso nós vimos como atualizar aplicações .NET automaticamente utilizando o NAppUpdate. Para mais informações sobre essa biblioteca, confira estes links:

The philosophy behind NAppUpdate

NAppUpdate – Application auto-update framework for .NET

Atenção! O NAppUpdate está ficando “sem dono”

Um detalhe que não posso deixar de mencionar aqui é que a pessoa que mais estava contribuindo com o NAppUpdate nos últimos tempos (o usuário “robinwassen” no GitHub) deixará de manter a biblioteca. Veja só a mensagem que ele deixou no GitHub da biblioteca algumas semanas atrás:

Isso pode ser preocupante caso alguém não assuma o desenvolvimento e manutenção da biblioteca nos próximos meses. Caso isso aconteça, as chances de a biblioteca acabar morrendo são grandes.

Opção 3: AutoUpdater.NET

Uma última opção de atualizador automático que eu quero mostrar para vocês nesse artigo é o AutoUpdater.NET. Ele também é uma biblioteca open source que implementa atualizações automáticas para aplicações .NET. A ideia é muito parecida com o NAppUpdate (aliás, a ideia do NAppUpdate veio dessa biblioteca). Através de um arquivo de manifesto, a biblioteca identificará se existe uma atualização disponível e, caso positivo, ela fará o download e instalação dessa atualização.

O arquivo de manifesto do AutoUpdater é muito mais simples do que o arquivo de manifesto do NAppUpdate. No caso do AutoUpdater, o XML contém somente um elemento chamado “version” (que indicará o número da versão que está disponível para download) e um outro elemento chamado “url“, que será o local de onde o AutoUpdater baixará a atualização para ser instalada:

<?xml version="1.0" encoding="UTF-8"?>
<item>
    <version>1.0.1.0</version>
    <url>file://d:\tmp\update\AtualizadorAplicacao.zip</url>
</item>

No exemplo de manifesto acima, estamos dizendo para o AutoUpdater que a versão “1.0.1.0” está disponível para ser baixada no caminho indicado. Com essa informação, o AutoUpdater verificará se a versão da aplicação é menor do que esse número e, caso positivo, ele entenderá que uma atualização está disponível. Um ponto importante é que, diferente do NAppUpdate (que trabalha com as versões dos arquivos), o AutoUpdater trabalha com a versão do assembly “entry point” da aplicação (ou seja, a versão do assembly do executável).

Para o elemento “url“, nós temos duas opções. A primeira delas é indicarmos o caminho para um executável. Com essa opção, nós teríamos que gerar um instalador (utilizando alguma outra ferramenta de instalador) contendo a versão mais nova da aplicação. Esse executável seria baixado e executado quando o usuário clicasse na opção para atualizar a aplicação.

Uma segunda opção para esse elemento é informarmos o caminho de um arquivo zip. Nesse caso, o AutoUpdater baixará o arquivo zip e descompactará na pasta da aplicação. Ou seja, basta ziparmos o executável e dlls da versão mais nova e o AutoUpdater se encarrega de descompactar no diretório da aplicação.

Seguindo o mesmo padrão do NAppUpdate, a biblioteca AutoUpdater também está disponível através do NuGet (só tome cuidado para adicionar a referência para o pacote oficial!):

Uma vez adicionada a referência, nós podemos acessar a classe do AutoUpdater, que fica no namespace “AutoUpdaterDotNET“. Com apenas uma linha de código nós conseguimos fazer a checagem de atualizações na nossa aplicação:

// C#
AutoUpdaterDotNET.AutoUpdater.Start(@"file://d:\tmp\autoupdater.xml");
' VB.NET
AutoUpdaterDotNET.AutoUpdater.Start("file://d:\tmp\autoupdater.xml")

O esquema do AutoUpdater é um pouco diferente do NAppUpdate. No caso do AutoUpdater, ele mesmo implementa uma interface padrão para facilitar a nossa vida. Uma vez que o AutoUpdater encontra uma nova versão para ser instalada, ele exibirá uma janela onde podemos escolher o que queremos fazer:

Note que a janela será exibida no idioma da região que estiver selecionada no sistema operacional (no meu caso em alemão, uma vez que a região do meu computador está definida como Alemanha). Se quiser alterar para um idioma específico, basta utilizar a propriedade CurrentCulture da classe AutoUpdater. No próprio GitHub da biblioteca conseguimos encontrar diversos exemplos de configurações específicas que podemos utilizar nas nossas aplicações. Por exemplo, nós podemos desabilitar o botão de “Skip“, o botão de “Remind later“, etc. E, caso você não tenha gostado da interface disponibilizada pelo AutoUpdater, você pode criar a sua própria interface para gerenciar a checagem de atualizações também (utilizando o evento “CheckForUpdateEvent“).

E com isso nós vimos como implementar atualizar as nossas aplicações .NET automaticamente utilizando a biblioteca AutoUpdater. Muito mais simples que o NAppUpdate, porém, menos flexível.

Squirrel: outra opção que eu não investiguei

Uma outra opção que eu acabei de encontrar enquanto estava escrevendo o artigo é o Squirrel, que também é uma biblioteca open source. O lema dessa biblioteca é “It’s like ClickOnce but Works“, então vale a pena dar uma olhada. Se você já tiver trabalhado com o Squirrel, deixe as suas impressões nos comentários.

Baixe o projeto de exemplo

Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário no final do artigo.

Concluindo

No artigo de hoje você conferiu tudo sobre aplicações que se atualizam sozinhas no .NET. Para conseguir essa façanha, temos que utilizar ferramentas de apoio.

A primeira ferramenta apresentada neste artigo foi o ClickOnce, que é uma ferramenta da própria Microsoft que implementa a funcionalidade de instalação e atualização automática de aplicações desktop. Apesar de ser bastante útil e fácil de utilizar, o ClickOnce vem com alguns problemas de brinde.

Em seguida, você conferiu como podemos utilizar a biblioteca NAppUpdate para fazer a atualização automática das nossas aplicações .NET. Ela é uma biblioteca um pouco complexa, porém, extremamente flexível.

Por fim, nós analisamos a biblioteca AutoUpdater.NET, que é bem mais simples do que a NAppUpdate, entretanto, com poucas flexibilidades no que diz respeito ao arquivo de manifesto de atualizações.

Dessas três opções, qual é a minha preferida? Confesso a você que eu só utilizei o ClickOnce em produção há muito tempo atrás. Hoje eu dia eu particularmente não utilizaria o ClickOnce se tivesse que fazer uma aplicação auto-atualizável. Se você precisa de bastante flexibilidade na hora de atualizar a sua aplicação, eu recomendo o NAppUpdate. Agora, se um simples arquivo zip descompactado já resolve a atualização da sua aplicação, acredito que o AutoUpdater seja a melhor opção.

E você? Já precisou atualizar aplicações desktop automaticamente? Qual tecnologia você utilizou? Encontrou algum desafio na implementação? Fico aguardando um relato das suas experiências logo abaixo na caixa de comentários!

Até a próxima!

André Lima

Photo by Pixabay used under Creative Commons
https://pixabay.com/en/update-upgrade-renew-improve-1672349/

Newsletter do André Lima

* indicates required



Powered by MailChimp

47 thoughts on “Como atualizar aplicações .NET automaticamente?

  • Lucas Almeida disse:

    Bom dia André, excelente artigo. Eu particularmente utilizei o ClickOnce em um projeto interno. Porém o mais chato dele como você próprio mencionou é o fato de não se poder escolher um destino na para nossa aplicação e também ter que comprar um certificado para assinar aplicação. Como é um aplicativo interno, optamos por não comprar um certificado, porém toda vez que vai instalar a primeira vez o aplicativo o usuário ‘grita’ falando que está instalando um programa não confiável…daí tem que explicar e bla bla bla…Vou testar as outras opção, gostei do NAppUpdate, porém o fato de que ela está ficando sem dono me deixou também preocupado. Abraços

    • andrealveslima disse:

      Olá Lucas, muito obrigado pelo comentário!

      Realmente o ClickOnce tem as suas chatices, como você falou.. O NAppUpdate me pareceu ser bem robusto.. Não sei se precisamos nos preocupar tanto assim com o principal colaborador estar abandonando o barco.. Acredito que alguém vá assumir o desenvolvimento algum dia desses.. Sem falar que a biblioteca já está um tanto quanto madura.. Vale a pena pelo menos testar para ver se encaixa bem no seu cenário de deployment..

      Enfim, depois volta aqui pra contar pra gente quais foram os resultados..

      Abraço!
      André Lima

  • deuzivaldo disse:

    Ótimo professor, muito bom, adorei. Ah professor, sobre aquele meu projeto, eu estou criando ele do zero de novo porque não funcionou mais. Não sei o que aconteceu. Obrigado por você ter me ajudado. Tenha um bom dia

  • Tadeu Botelho disse:

    Olá André!

    Obrigado por mais essa contribuição. Pois me ajudou muito ao dar uma olhada em suas explicações e observações em relação aos atualizadores.

    Fiz alguns testes com eles e realmente os achei um pouco limitados em relação aos recursos disponíveis. Mas o princípio é o mesmo do atualizador que estou aperfeiçoando, para atualização de vários sistemas que funcionam em conjunto, dentro da mesma plataforma compartilhada entre ambos. Ou seja: Tenho o sistema 01, sistema 02, sistema 03… (Desenvolvidos com linguagens diferentes e conversando entre si de maneira integrada), todos estão sendo atualizados por um software que já existe há 10 anos. Porém, agora seus recursos de atualização estão sendo remontados para operar online. Os desafios estão em questões de otimização. E na construção, estou utilizando C# com recursos da .Net e esta ficando muito bom.

    Tenho acompanhado suas publicações há alguns meses. Quero parabenizá-lo e incentivá-lo a manter seus textos em atividade. Pois são bem esclarecedores pelo fato de exibirem vários assuntos bem bacanas (Como os atualizadores de hoje).

    Grande abraço

    • andrealveslima disse:

      Olá Tadeu, muito obrigado pelo elogio! Eu que agradeço por você ter acompanhado as publicações.. :)

      Desconsiderando o ClickOnce, o que exatamente você achou limitado nas outras bibliotecas? Aqui onde eu trabalho a gente também tem um atualizador próprio para um sistema específico.. Só que ele funciona basicamente seguindo a mesma ideia dessas bibliotecas.. Se soubéssemos da existência delas anteriormente, provavelmente não teríamos desenvolvido um sistema próprio..

      Um forte abraço!
      André Lima

  • Giancarlo Carraro disse:

    Excelente artigo. Nunca gostei do ClickOnce pelas limitações dele, mas fiquei sem tempo de procurar outras soluções então acabei utilizando “quebra-galhos”. Vai me ajudar muito as suas observações.
    Obrigado por dedicar o seu tempo a nos ajudar.

    • andrealveslima disse:

      Olá Giancarlo, muito obrigado pelo comentário! Espero que você goste das outras opções além do ClickOnce.. :)

      Qualquer coisa estamos aí..

      Abraço!
      André Lima

  • ANDRE LUIZ G DIOGO disse:

    Boa Tarde… excelente tópico, novamente meus parabéns…

    Eu trabalho atualizando varias tipos de executáveis a partir de um http://FTP.. a ideia é um aplicativo que conecta no FTP e verifica as versões em um TXT que segue um layout separados por pipe (Nome | Versão | Local Destino ) mais ou menos assim.. pois txt qualquer máquina consegue ler.. o atualizador ao ver que existe um novo exe na base de dados em txt, faz o download do executável via FTP e substitui o anterior.. foi esta maneira que encontrei para poder trabalhar com vários programas de fornecedores distintos e com recurso do http://FTP... mas show de bola. .espero um dia poder melhorar meu programa de atualização para ficar mais robusto… uma falha que ainda não corrigi é de não verificar o md5 apos download, pode ser que as vezes possa vim corrompido :(

    abraço André e obrigado pelos tópicos…

    • andrealveslima disse:

      Olá André, muito obrigado pelo comentário!

      Não tem problema nenhum construir uma sistemática própria de atualização.. Aqui onde eu trabalho nós construimos uma customizada também, baseada em web services.. Só é importante conhecer as ferramentas que já trazem essa funcionalidade pronta, dessa forma sempre que precisarmos desse tipo de atualização automática em algum projeto, podemos analisar se essas soluções prontas já não atendem à demanda..

      Quanto ao esquema do MD5, eu escrevi um artigo sobre comparação de hashes de arquivos.. Não sei se você chegou a dar uma olhada:

      Calculando o hash de arquivos para verificação de integridade com C# e VB.NET

      Talvez te ajude na hora de implementar essa checagem no seu sistema de atualização..

      Abraço!
      André Lima

  • Sidney disse:

    Como faria para atualizar vários arquivos da aplicação utilizando o NappUpdate?
    Pois dependendo da versão ele poderá conter outras dependências/dll, teria que criar um xml para cada arquivo?

    • andrealveslima disse:

      Olá Sidney!

      Eu particularmente não testei, mas a ideia é que você tenha várias tags “FileUpdateTask” no mesmo XML de definição.. Cada tag dessa corresponderia a um arquivo que deverá ser atualizado.. Entendeu a ideia?

      Abraço!
      André Lima

  • WEDER FRANÇA disse:

    Olá André, bom dia!
    Parabens pelo conteudo, muito bem explicado.
    Sou iniciante em c# e criei uma aplicação windows form.
    para usar o clickOnce terei que criar uma pagina na internet
    para atualização do aplicado? esta seria a unica forma de uma
    atualização automática?
    abraços…

    • andrealveslima disse:

      Olá Weder, muito obrigado pelo comentário!

      Se você quiser ter uma atualização automática, independente da opção que você escolher, você precisará de qualquer forma disponibilizar as versões em um local (servidor) acessível pela internet.. Com o ClickOnce você precisa sim de um servidor web (IIS) rodando por trás dos panos.. Se o Azure for uma opção para você, recomendo este vídeo do André Secco, que eu mencionei no meio do artigo:

      Implantação de aplicativos Auto-Atualizáveis com o ClickOnce

      Agora, se esse tipo de estrutura for muito complexa para você manter, recomendo que você dê uma olhada nas outras opções de ferramentas / bibliotecas que eu apresentei no artigo..

      Abraço!
      André Lima

      • WEDER FRANÇA disse:

        Obrigado Andre!

        Então, como disse ainda estou iniciando no mundo de TI.
        Criei um sistema de “Ordem de Servico” e recentemente acrescentei
        nele a emissão de “Nota fiscal Eletronica.
        Agora o cliente gera a OS e caso queira a NFe também.
        Hoje tem apenas 3 pessoas usando, e as atualizações sempre envio por email, mas vejo que esta prática não é a melhor.
        o certo seria assim que o cliente acessar o sistema já buscar atualizações.
        Vou ter que aprofundar na criação de uma pagina na internet para disponibilizar estes arquivos então.
        Vai ser outra batalha, nunca mexi com programação web. rrsrsrs

        • andrealveslima disse:

          Olá Weder!

          Entendi o seu cenário.. Não se preocupe, o conhecimento que você terá que ter para disponibilizar as novas versões na web não será muito grande.. Se você ficar com alguma dúvida no processo, é só entrar em contato..

          Abraço!
          André Lima

  • denis disse:

    Achei interessante o WixToolset, que também da suporte ao auto-update http://wixtoolset.org/

    • andrealveslima disse:

      Olá Denis!

      Já tinha ouvido falar do WiX uns tempos atrás, mas nunca trabalhei com ele.. Não sabia que ele dava suporte a atualizações automáticas também..

      Coloquei ele aqui na minha lista de “itens a estudar / investigar”.. Obrigado pelo toque.. :)

      Abraço!
      André Lima

  • André Spilari disse:

    Bom dia ANdré tudo bem? Estou com problema com o ClickOnce

    Mensagem de Log

    ———————————————————————————–

    INFORMAÇÕES SOBRE VERSÕES DE PLATAFORMAS
    Windows : 10.0.16299.0 (Win32NT)
    Common Language Runtime : 4.0.30319.42000
    System.Deployment.dll : 4.7.2556.0 built by: NET471REL1
    clr.dll : 4.7.2600.0 built by: NET471REL1LAST
    dfdll.dll : 4.7.2556.0 built by: NET471REL1
    dfshim.dll : 10.0.16299.15 (WinBuild.160101.0800)

    ORIGENS
    URL da Implantação : file:///C:/Users/Andr%C3%A9%20Spilari/Downloads/Automacao.application
    URL do Provedor de Implantação : http://www.zipersoft.com.br/atualizacoes/automacao/Automacao.application
    Servidor : Apache/2.4.29 (Unix) OpenSSL/1.0.1e-fips mod_fcgid/2.3.9

    IDENTIDADES
    Identidade da Implantação : Automacao.application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=18bfd093ca5e7b4b, processorArchitecture=msil

    RESUMO DO APLICATIVO
    * Aplicativo instalável.

    RESUMO DOS ERROS
    Um resumo dos erros pode ser encontrado a seguir. Os detalhes desses erros são relacionados posteriormente no log.
    * Exceção na ativação de C:\Users\André Spilari\Downloads\Automacao.application. As seguintes mensagens de erro foram detectadas:
    + Exceção ao ler o manifesto de http://www.zipersoft.com.br/atualizacoes/automacao/Application%20Files/Automacao_1_0_0_0/Automacao.exe.manifest: talvez o manifesto não seja válido ou o arquivo não pôde ser aberto.
    + A análise e a criação de DOM do manifesto resultaram em erro. Os seguintes erros de análise foram observados:
    -HRESULT: 0x80070c81
    Linha inicial: 0
    Coluna inicial: 0
    Arquivo de host:
    + Exceção de HRESULT: 0x80070C81

    RESUMO DA FALHA DA TRANSAÇÃO DE ARMAZENAMENTO DO COMPONENTE
    Nenhum erro de transação foi detectado.

    AVISOS
    Não houve avisos durante esta operação.

    STATUS DO ANDAMENTO DA OPERAÇÃO
    * [04/01/2018 11:49:05] : A ativação de C:\Users\André Spilari\Downloads\Automacao.application foi iniciada.
    * [04/01/2018 11:49:06] : O processamento do manifesto da implantação foi concluído com êxito.
    * [04/01/2018 11:49:06] : A instalação do aplicativo foi iniciada.

    DETALHES DOS ERROS
    Os erros a seguir foram detectados durante esta operação.
    * [04/01/2018 11:49:08] System.Deployment.Application.InvalidDeploymentException (ManifestParse)
    – Exceção ao ler o manifesto de http://www.zipersoft.com.br/atualizacoes/automacao/Application%20Files/Automacao_1_0_0_0/Automacao.exe.manifest: talvez o manifesto não seja válido ou o arquivo não pôde ser aberto.
    – Origem: System.Deployment
    – Rastreamento de pilha:
    em System.Deployment.Application.ManifestReader.FromDocument(String localPath, ManifestType manifestType, Uri sourceUri)
    em System.Deployment.Application.DownloadManager.DownloadApplicationManifest(AssemblyManifest deploymentManifest, String targetDir, Uri deploymentUri, IDownloadNotification notification, DownloadOptions options, Uri& appSourceUri, String& appManifestPath)
    em System.Deployment.Application.ApplicationActivator.DownloadApplication(SubscriptionState subState, ActivationDescription actDesc, Int64 transactionId, TempDirectory& downloadTemp)
    em System.Deployment.Application.ApplicationActivator.InstallApplication(SubscriptionState& subState, ActivationDescription actDesc)
    em System.Deployment.Application.ApplicationActivator.PerformDeploymentActivation(Uri activationUri, Boolean isShortcut, String textualSubId, String deploymentProviderUrlFromExtension, BrowserSettings browserSettings, String& errorPageUrl, Uri& deploymentUri)
    em System.Deployment.Application.ApplicationActivator.PerformDeploymentActivationWithRetry(Uri activationUri, Boolean isShortcut, String textualSubId, String deploymentProviderUrlFromExtension, BrowserSettings browserSettings, String& errorPageUrl)
    — Fim do rastreamento de pilha do local anterior onde a exceção foi gerada —
    em System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    em System.Deployment.Application.ApplicationActivator.PerformDeploymentActivationWithRetry(Uri activationUri, Boolean isShortcut, String textualSubId, String deploymentProviderUrlFromExtension, BrowserSettings browserSettings, String& errorPageUrl)
    em System.Deployment.Application.ApplicationActivator.ActivateDeploymentWorker(Object state)
    — Exceção interna —
    System.Deployment.Application.InvalidDeploymentException (ManifestParse)
    – A análise e a criação de DOM do manifesto resultaram em erro. Os seguintes erros de análise foram observados:
    -HRESULT: 0x80070c81
    Linha inicial: 0
    Coluna inicial: 0
    Arquivo de host:
    – Origem: System.Deployment
    – Rastreamento de pilha:
    em System.Deployment.Application.Manifest.AssemblyManifest.LoadCMSFromStream(Stream stream)
    em System.Deployment.Application.Manifest.AssemblyManifest..ctor(FileStream fileStream)
    em System.Deployment.Application.ManifestReader.FromDocument(String localPath, ManifestType manifestType, Uri sourceUri)
    — Exceção interna —
    System.Runtime.InteropServices.COMException
    – Exceção de HRESULT: 0x80070C81
    – Origem: System.Deployment
    – Rastreamento de pilha:
    em System.Deployment.Internal.Isolation.IsolationInterop.CreateCMSFromXml(Byte[] buffer, UInt32 bufferSize, IManifestParseErrorCallback Callback, Guid& riid)
    em System.Deployment.Application.Manifest.AssemblyManifest.LoadCMSFromStream(Stream stream)

    DETALHES DA TRANSAÇÃO DE ARMAZENAMENTO DO COMPONENTE
    Nenhuma informação de transação está disponível.

    ———————————————————————————–

    Se puder me ajudar eu cheguei a fazer essa resposta sua no forum (https://social.msdn.microsoft.com/Forums/en-US/3d0c4382-9b48-4d28-9b79-25607e668074/problem-with-installing-clickonce-after-adding-reportviewercontrol-14-to-the-project?forum=winformssetup)mas não deu certo.

    • andrealveslima disse:

      Olá André!

      Que estranho hein.. Como é que está a sua lista de Application Files do ClickOnce? Não tem nada nessa lista que não faça realmente parte do projeto?

      Abraço!
      André Lima

  • Ramon Shuan disse:

    Boa noite Andre!

    Como ficaria a forma de download sem a a opção de download para o cliente?
    Por exemplo estou tentando fazer a opcao 3 mais gostaria que a tela nao aparecesse para o cliente clicar em baixa, gostaria de ja baixar o arquivo de vez

    • andrealveslima disse:

      Olá Ramon!

      Na página da biblioteca tem uma seção chamada “Handling updates manually”, que mostra como fazer um comportamento customizado na hora de baixar a nova versão.. Você pode se basear nela ignorando todas as partes de UI (os MessageBoxes exibidos para o usuário confirmar se quer instalar a nova versão).. O link é este:

      Página oficial AutoUpdater.NET

      Abraço!
      André Lima

  • André,
    Bom dia!
    Não sei se você já testou o clickonce do VS2017 mas, quando tiver oportunidade dá uma olhada na quantidade absurda de dlls “agregadas” ao Application Files.
    Notei também que o upload, que nunca foi lá essas coisas, sempre se mostrou muito lento em todas as versões do VS, ficou ainda mais lento.
    Não raras vezes a publicação é abortada por não conseguir “upar” todos os arquivos agregados.
    Eu inclusive acabei instalando um servidor FTP para fazer minhas publicações e incrementando a versão manualmente.

    • andrealveslima disse:

      Olá Nelson!

      Ainda não tive a oportunidade de trabalhar “em produção” com o ClickOnce do VS 2017.. Mas, estranho ele agregar tandas dlls assim.. Ele deveria respeitar as referências do seu projeto, assim como nas versões anteriores do Visual Studio..

      Se você encontrar um tempinho, manda uns screenshots das referências do seu projeto e das dlls que o ClickOnce está agregando ao Application Files para eu dar uma olhada..

      Abraço!
      André Lima

      • Olá André,
        Enviei dois prints de tela no seu email de contato.
        Repara só a quantidade!!!

        • andrealveslima disse:

          Olá Nelson!

          Tá muito estranho esse monte de arquivo aí.. Você já deu uma olhada na parte de “Application Files” da aba “Publish” do seu projeto para ver o que o ClickOnce está detectando como referências da sua aplicação? Eu acredito que ele esteja detectando esse monte de dll por causa de alguma referência do seu projeto..

          Um teste que você pode fazer é criar um projeto Windows Forms novo e tentar fazer um deploy para ver se ele vai mandar esse monte de arquivo também, mesmo o projeto estando “vazio”..

          Abraço!
          André Lima

          • Olá André,
            Fiz o teste aqui e esse “aglomerado” de dlls surge após instalar via Nuget a Microsoft.ReportingServices.ReportViewerControl.WinForms.
            O problema é que meus relatórios foram todos feitos no reportviewer, resolvi abandonar o Cristal Report há algum tempo.

          • Levantei um questionamento lá no site do Nuget e vamos ver se eles respondem.
            Sempre usei o Nuget pra instalar a ReportService, isso começou há uns 3 ou 4 updates atrás.
            Tá parecendo que foi um descuido da equipe do SQLRSNuget.

            Um Abraço,

          • andrealveslima disse:

            Olá Nelson!

            Eu dei uma olhada na última release desse pacote do Report Viewer e, tirando as dlls com as traduções (que são as pastas “de”, “es”, “fr”, “pt”, etc e que você pode eliminar dos pré-requisitos do ClickOnce caso você não esteja trabalhando com esses idiomas), só tem 9 dlls nesse pacote.. Além disso, ele só tem dependência com o pacote Microsoft.SqlServer.Types, que é somente mais uma dll.. Ou seja, tirando as dlls de tradução, no total seriam somente 10 dlls relacionadas ao Report Viewer.. No seu caso você ficou com mais do que essa quantidade de dlls?

            Abraço!
            André Lima

          • André,

            Tem bem mais,
            Até a ImageCatalog do VS está entrando no lote.

          • Mandei no seu email mais algumas imagens pra ver a quantidade de dlls.

            Um Abraço,

          • andrealveslima disse:

            Olá Nelson!

            Finalmente consegui testar essa parada.. Realmente uma vez adicionada a referência para o Report Viewer através do NuGet, o deployment do ClickOnce fica poluído com um monte de dlls desnecessárias.. O problema é que o pacote do Report Viewer está adicionando uma referência desnecessária para a dll “Microsoft.ReportViewer.Design”, que por sua vez tem dependência com várias coisas internas do Visual Studio..

            Não sei por que o pacote está adicionando essa referência, uma vez que, até onde eu sei, ela só é utilizada na hora de desenharmos os relatórios dentro do Visual Studio.. Ou seja, ela não é necessária no deployment da aplicação para que ela funcione no computador destino.. O correto seria a especificação desse pacote no NuGet ignorar essa dll na hora de fazer as referências no projeto, ou até mesmo nem distribuir essa dll dentro desse pacote..

            Enfim, se você excluir essa referência, o seu deployment do ClickOnce voltará ao tamanho “normal”:

            E quanto às dlls de localização (das pastas “de”, “es”, “fr”, etc), isso é normal mesmo.. Você tem que excluir essas dlls manualmente do “Application Files” do ClickOnce caso não precise desses idiomas (o que provavelmente é o caso)..

            Abraço!
            André Lima

          • Realmente André,
            Está corretíssimo!!
            Eu já havia retirado do Aplication Files do ClickOnce as dlls que sobravam, mas não tinha reparado nessa dll do Design.
            Muito grato pela atenção!!

          • andrealveslima disse:

            Olá Nelson! Pois é.. Essa dll não era para estar referenciada, acho que o pessoal da Microsoft deu uma bobeada com esse pacote do NuGet.. Mas, enfim, pelo menos agora já sabemos a fonte do problema.. :)

            Abraço!
            André Lima

  • Olá André,

    Eu já li sobre eles uma vez, mas quando precisei implementar um recurso de atualização, optei por desenvolver uma engine própria. Montei um Webservice, fiz uma aplicação para gerar o pacote de atualização, pegando todos os arquivos necessários e compactando no final. Este pacote para atualização segue um padrão de nome e ele é colocado na pasta do webservice, ai a aplicação acessa o ele, enviando sua versão, e com isso o é identificado se tem um pacote a ser atualizado e devolve o pacote por meio de stream. Do outro lado quando receber, é feito uma comparação com o checksum para saber se esta completo o arquivo, é feito a descompactação e copiado os novos arquivos. Claro que é muito trabalhoso e tem que cercar várias situações de falhas, que com certeza, essas ferramentas já tratam isso, mas tive um grande ganho de conhecimento, e no final quando ver funcionar, é muito legal.

    • andrealveslima disse:

      Olá Ezequiel, muito obrigado pelo comentário!

      Eu também, quando tive que implementar uma funcionalidade desse tipo em uma aplicação aqui da empresa, acabei desenvolvendo uma solução própria, também baseada em web service e com o mesmo comportamento que você descreveu.. Na época eu não conhecia essas ferramentas que eu listei aqui no artigo, senão eu teria utilizado alguma delas.. Mas, como você mesmo disse, acabei aprendendo bastante ao desenvolver essa funcionalidade “na mão”, então tá valendo! :)

      A propósito, parabéns pelo seu site.. Dei uma olhada lá e você aborda temas muito interessantes.. Talvez valeria a pena detalhar essa implementação de atualizador que você fez em um artigo lá no seu site.. ;)

      Abraço!
      André Lima

  • Marcelo Silva disse:

    André, excelente artigo.

    Muito bem escrito….

    Meus parabéns….

    A mim, particularmente, me ajudou muito pois eu estava precisando desenvolver um esquema de atualização automática para o meu sistema.

    Consegui utilizando o AutoUpdater.net

    Sou grato por compartilhar com todos o seu conhecimento.

    Deus lhe pague.

    Um abraço!

    • andrealveslima disse:

      Olá Marcelo!

      Muito obrigado pelo comentário! Fico feliz por ter conseguido ajudar de alguma maneira.. :)

      Abraço!
      André Lima

  • Herbert Lins disse:

    Valeu pela dica, e como vou fazer atualização em rede, para um sistema interno vou utilizar a versão mais simples de configurar o AutoUpdate.Net. Com arquivo ZIP. Muito Obrigado pela dica!

  • Andrew disse:

    Eu utilizo, um servidor e baixo os arquivos, porém meu projeto está crescendo e estou em duvidas de como organizar o projeto, de forma que a cada atualização não baixe “tudo” novamente, somente o que foi atualizado. Você teria alguma sugestão? Não sei se criar varios projetos dentro da solution seria viavel.

    • andrealveslima disse:

      Olá Andrew!

      É justamente isso que você tem que fazer (separar a solution em vários projetos).. Você poderia separar em projetos tipo:

      1) Acesso a dados
      2) Lógica de negócio
      3) Interfaces do usuário

      Etc.. Cada um sendo uma dll.. Dessa forma, se você só alterar a lógica de negócio, somente essa dll teria que ser atualizada, e não a aplicação toda..

      Abraço!
      André Lima

      • Andrew disse:

        Obrigado andre pela resposta, hoje ele já é organizado assim, mas de certa forma sempre preciso atualizar tudo, por que vamos pensar, adicionei uma tela então as 3 dlss

        1) Acesso a dados
        2) Lógica de negócio
        3) Interfaces do usuário

        Precisariam se alteradas, o problema é que minha “dll” de logica de negocios ta ficando muito grande, e estou tendo problemas com pessoas de “net duvidosa”.

        Porem acho que achei uma solução, zipar as “dlls” depois checar usando a hash, que vc ensinou.

        Ai baixo o arquivo e desipo. pelo menos assim a atualização já diminui um bom tanto.

        Obs.: o site não ta mandando quando vc responde.
        Me inscrevi também para novas publicações e não recebi nada no email.

        Vlw!

        • andrealveslima disse:

          Olá Andrew!

          Que bom que você conseguiu resolver zipando as dlls.. Mas, se você está notando que a dll de lógica está ficando muito grande, talvez valha a pena dar uma dividida nela, quebrando em áreas de negócio.. Quanto antes você fizer essa divisão, mais fácil será..

          Quanto à inscrição para novas publicações, você não recebeu nada porque eu ainda não publiquei nada novo.. Estou dando uma pausa nas publicações para colocar as coisas em ordem aqui em casa.. Assim que tudo estiver OK, eu voltarei a publicar, aí avisarei na newsletter..

          Abraço!
          André Lima

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *