Pergunta

Quero atualizar meu exe do servidor remoto.Então, quando o botão clicado no meu aplicativo wpf ele irá baixar o remoto e também um arquivo txt remoto e substituir os atuais na mesma pasta que exe em execução.Portanto, ele substituirá o arquivo txt e exe atual enquanto meu exe estiver em execução.Como posso conseguir isso?

O host remoto é um url como www.mydomain.com/MyAPP.exe

aplicativo wpf, c # 4.0

Foi útil?

Solução

A maneira como resolvemos esse problema foi criando um shell exe igual ao que foi instalado e implantado inicialmente nas máquinas clientes.

O programa executável "real" é armazenado em um subdiretório desse aplicativo inicial.Quando o aplicativo shell é iniciado, depois de baixar e instalar todas as atualizações do aplicativo real, ele inicia o executável do aplicativo real em um AppDomain separado.

Aqui está o núcleo do aplicativo "real" sendo iniciado de dentro do aplicativo shell:

        System.AppDomainSetup oSetup = new System.AppDomainSetup();
        string sApplicationFile = null;

        // Use this to ensure that if the application is running when the user performs the update, that we don't run into file locking issues.
        oSetup.ShadowCopyFiles = "true";
        oSetup.ApplicationName = sAppName;

        // Generate the name of the DLL we are going to launch
        sApplicationFile = System.IO.Path.Combine(sApplicationDirectory, sAppName + ".exe");

        oSetup.ApplicationBase = sApplicationDirectory;
        oSetup.ConfigurationFile = sApplicationFile + ".config";
        oSetup.LoaderOptimization = LoaderOptimization.MultiDomain;

        // Launch the application
        System.AppDomain oAppDomain = AppDomain.CreateDomain(sAppName, AppDomain.CurrentDomain.Evidence, oSetup);
        oAppDomain.SetData("App", sAppName);
        oAppDomain.SetData("User", sUserName);
        oAppDomain.SetData("Pwd", sUserPassword);

        oAppDomain.ExecuteAssembly(sApplicationFile);

        // When the launched application closes, close this application as well
        Application.Exit();

Observe que, em nossa versão, o aplicativo shell coleta o nome de usuário e a senha do usuário para acessar o site de atualização corretamente.Esses dados são então passados para o aplicativo "real" por meio do método SetData no AppDomain.

Outras dicas

A solução depende do seu caso particular. Mas não há solução reta, porque você não pode atualizar assemblies enquanto eles são carregados na memória e sendo usados. Eu posso propor 2 soluções: usando Copiadora de sombra e usando algum tipo de ajudante executável. Eu usei os dois.

cópia de sombra.

A maneira óbvia é fazer seu executável principal para ser copiado sombra, substituí-lo enquanto seu aplicativo estiver sendo executado e reinicie o aplicativo. Mas você não pode tornar seu domínio de aplicativo padrão para ser copiado sombra, apenas os domínios do aplicativo secundário podem ser. Mas você ainda pode mover todo o seu código para outro assembly (digamos, mainapplib.dll) e reescreva seu executável do aplicativo principal (MainApp.exe) para que ele contenha apenas "Código do carregador". Este código de carregador tem que criar outro domínio de aplicativo, configurá-lo para ser copiado em sombra e, em seguida, execute sua lógica de programa no domínio do aplicativo secundário. Cuidado para não ter referências diretas do seu principal domínio do aplicativo em mainapplib.dll, porque esse assembly será carregado no domínio do aplicativo principal, que não é copiado de sombra e o arquivo de montagem será bloqueado. Na maioria dos casos, você pode ir com appdomain.ExecutEsteaseSeSEsmbly () Métodos.

executável auxiliar

A ideia é usar algum tipo de federal update . Seu aplicativo principal permanece inalterado, você só adiciona uma pequena quantidade de código, para que seu aplicativo faça o download de atualização, coloque-o em pasta temporária e, em seguida, o aplicativo principal inicia o finalizador de atualização ( em processo separado ) e sai. Atualizar o finalizador aguarda até o seu aplicativo fechar e, em seguida, copia novos arquivos da pasta temporária para sua pasta de aplicativo, substituindo todos os arquivos. Atualizar o finalizador não pode substituir seu próprio executável, mas isso pode ser feito pelo aplicativo principal antes de iniciar o finalizador de atualização. Depois de copiar arquivos de atualização do finalizador executar seu aplicativo.

p.s. Pessoalmente eu prefiro a solução anterior porque envolve algum tipo de mágica vodu usando domínios de aplicativos, reflexão, montagens e.t.c. E pode ser evoluído para usar plugins se você precisar (por exemplo, via framework MEF ).>). Mas o último é mais fácil de entender, especialmente se você nunca trabalhou com domínios de aplicativos e assemblies manuais carregando, é bastante simples.

Você provavelmente poderia usar ClickOnce (com base no seu comentário acimaVocê estaria preparado para ter outra assembléia obter o exe ... como o outro pôster mencionado, você não pode substituir uma montagem em execução).Você pode configurá-lo para verificar em vários horários (por exemplo, na inicialização) para novas versões e baixá-las automaticamente.É uma solução muito robusta e você pode fazer muito com as assembléias de implantação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top