Estavam ansiosos pela segunda parte dessa série de artigos, não é? 🙂
Em continuidade ao artigo anterior, prosseguiremos com o tutorial de implementação de atualização automática em um projeto Delphi. A primeira parte abordou apenas os recursos de apoio, como o registro em um serviço de hospedagem, instalação do FileZilla e criação dos arquivos INI. Hoje, partiremos para a codificação!
Projeto
Em primeiro lugar, um atualizador automático exige, claro, uma tela de atualização. Para exemplo, faremos uma tela simples. Crie um novo formulário e adicione os seguintes componentes:
Além disso, para acessar o diretório FTP, utilizaremos o componente TIdFTP
, da paleta IndyClients. Arraste este componente para a tela de atualização e configure as seguintes propriedades:
- Host: endereço do FTP, fornecido no FreeWHA (veja a parte 1 dessa série)
- Username: login do FTP, geralmente o mesmo que o host
- Password: senha do FTP
- Passive: True
- TransferType: ftBinary
Codificação
Declare também uma variável de classe chamada FTamanhoTotal
. Ela será útil nos eventos do componente TIdFTP
:
1 2 |
private FTamanhoTotal: integer; |
Para manter o código limpo, precisaremos também de uma função que irá nos retornar o diretório em que se encontra o executável:
1 2 3 4 5 6 7 8 |
{ declaração } function ObterDiretorioDoExecutavel: string; { implementação } function TForm1.ObterDiretorioDoExecutavel: string; begin result := ExtractFilePath(Application.ExeName); end; |
Para ignorar as exceções de “Connection Closed Gracefully”, disparada por alguns servidores, inclua a unit IdException
na uses. Ela será necessária no bloco except.
1 2 |
uses IdException; |
O próximo método a ser implementado é a conexão com o servidor FTP, envolvido em um bloco try/except para tratar possíveis exceções:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{ declaração } function ConectarAoServidorFTP: boolean; { implementação } function TForm1.ConectarAoServidorFTP: boolean; begin // desconecta, caso tenha sido conectado anteriormente if IdFTP1.Connected then IdFTP1.Disconnect; try IdFTP1.Connect; result := True; except On E:Exception do begin ShowMessage('Erro ao acessar o servidor de atualização: ' + E.Message); result := False; end; end; end; |
Leitura dos arquivos INI
Em seguida, implementaremos dois métodos: um para ler o número da versão instalada no cliente e outro para ler o número da versão mais recente da aplicação, disponível no FTP. Como essas informações estão armazenadas em arquivos INI, usaremos a classe TIniFile
para abri-los e o método ReadString
para retornar o valor da chave.
ObterNumeroVersaoLocal:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
uses IniFiles; { declaração } function ObterNumeroVersaoLocal: smallint; { implementação } function TForm1.ObterNumeroVersaoLocal: smallint; var lNumeroVersao: string; lArquivoINI: TIniFile; begin // abre o arquivo "VersaoLocal.ini" lArquivoINI := TIniFile.Create(ObterDiretorioDoExecutavel + 'VersaoLocal.ini'); try // lê o número da versão lNumeroVersao := lArquivoINI.ReadString('VersaoLocal', 'Numero', EmptyStr); // retira os pontos (exemplo: de "1.0.0" para "100") lNumeroVersao := StringReplace(lNumeroVersao, '.', EmptyStr, [rfReplaceAll]); // converte o número da versão para número result := StrToIntDef(lNumeroVersao, 0); finally FreeAndNil(lArquivoINI); end; end; |
ObterNumeroVersaoFTP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
{ declaração } function ObterNumeroVersaoFTP: smallint; { implementação } function TForm1.ObterNumeroVersaoFTP: smallint; var lNumeroVersao: string; lArquivoINI: TIniFile; begin // deleta o arquivo "VersaoFTP.ini" do computador, caso exista, // evitando erro de arquivo já existente if FileExists(ObterDiretorioDoExecutavel + 'VersaoFTP.ini') then DeleteFile(ObterDiretorioDoExecutavel + 'VersaoFTP.ini'); // baixa o arquivo "VersaoFTP.ini" para o computador IdFTP1.Get('atualizacao/VersaoFTP.ini', ObterDiretorioDoExecutavel + 'VersaoFTP.ini', True, True); // abre o arquivo "VersaoFTP.ini" lArquivoINI := TIniFile.Create(ObterDiretorioDoExecutavel + 'VersaoFTP.ini'); try // lê o número da versão lNumeroVersao := lArquivoINI.ReadString('VersaoFTP', 'Numero', EmptyStr); // retira os pontos (exemplo: de "1.0.1" para "101") lNumeroVersao := StringReplace(lNumeroVersao, '.', EmptyStr, [rfReplaceAll]); // converte o número da versão para número result := StrToIntDef(lNumeroVersao, 0); finally FreeAndNil(lArquivoINI); end; end; |
Download do pacote de atualização
Agora, segue a definição do método que irá baixar o arquivo de atualização (executável) do servidor FTP. Para isso, atente-se ao uso do Get
do componente TIdFTP
, que consiste em buscar o arquivo do servidor e gravá-lo em um diretório no disco. Repare que o Get
também foi utilizado no método anterior para baixar o arquivo INI.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
{ declaração } procedure BaixarAtualizacao; { implementação } procedure TForm1.BaixarAtualizacao; begin try // deleta o arquivo "Atualizacao.rar", caso exista, // evitando erro de arquivo já existente if FileExists(ObterDiretorioDoExecutavel + 'Atualizacao.rar') then DeleteFile(ObterDiretorioDoExecutavel + 'Atualizacao.rar'); // obtém o tamanho da atualização e preenche a variável "FnTamanhoTotal" FnTamanhoTotal := IdFTP1.Size('atualizacao/Atualizacao.rar'); // faz o download do arquivo "Atualizacao.rar" IdFTP1.Get('atualizacao/Atualizacao.rar', ObterDiretorioDoExecutavel + 'Atualizacao.rar', True, True); except On E:Exception do begin // ignora a exceção "Connection Closed Gracefully" if E is EIdConnClosedGracefully then Exit; ShowMessage('Erro ao baixar a atualização: ' + E.Message); // interrompe a atualização Abort; end; end; end; |
Quando a atualização é baixada, precisamos descompactá-la para substituir o executável existente pelo novo executável. Essa operação pode ser realizada através do método RenameFile
, para renomear o executável desatualizado, e pelo ShellExecute
, para descompactar a atualização utilizando a linha de comando do 7-Zip.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
uses ShellAPI; { declaração } procedure DescompactarAtualizacao; { implementação } procedure TForm1.DescompactarAtualizacao; var lNomeArquivoAtualizacao: string; begin // deleta o backup anterior, ou melhor, da versão anterior, // evitando erro de arquivo já existente if FileExists(ObterDiretorioDoExecutavel + 'Sistema_Backup.exe') then DeleteFile(ObterDiretorioDoExecutavel + 'Sistema_Backup.exe'); // Renomeia o executável atual (desatualizado) para "Sistema_Backup.exe" RenameFile(ObterDiretorioDoExecutavel + 'Sistema.exe', ObterDiretorioDoExecutavel + 'Sistema_Backup.exe'); // armazena o nome do arquivo de atualização em uma variável lNomeArquivoAtualizacao := ObterDiretorioDoExecutavel + 'Atualizacao.rar'; // executa a linha de comando do 7-Zip para descompactar o arquivo baixado ShellExecute(0, nil, '7z', PWideChar(' e -aoa ' + lNomeArquivoAtualizacao + ' -o' + ObterDiretorioDoExecutavel), '', SW_SHOW); end; |
Por fim, é necessário atualizar o número da versão no arquivo INI local. Este procedimento mantém o usuário informado de que está com a versão mais recente da aplicação e garante que a mesma atualização não seja baixada novamente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ declaração } procedure AtualizarNumeroVersao; { implementação } procedure TForm1.AtualizarNumeroVersao; var lArquivoLocal, lArquivoFTP: TIniFile; lNumeroNovaVersao: string; begin // abre os dois arquivos INI lArquivoFTP := TIniFile.Create(ObterDiretorioDoExecutavel + 'VersaoFTP.ini'); lArquivoLocal := TIniFile.Create(ObterDiretorioDoExecutavel + 'VersaoLocal.ini'); try // obtém o número da nova versão no arquivo "VersaoFTP.ini"... lNumeroNovaVersao := lArquivoFTP.ReadString('VersaoFTP', 'Numero', EmptyStr); // ... e grava este número no arquivo "VersaoLocal.ini" lArquivoLocal.WriteString('VersaoLocal', 'Numero', lNumeroNovaVersao); finally FreeAndNil(lArquivoFTP); FreeAndNil(lArquivoLocal); end; end; |
Barra de progresso
Opa, mas espere aí… lembram-se que adicionamos um componente TProgressBar
na tela de atualização? Pois bem, para aprimorar a usabilidade da nossa tela de atualização, exibiremos o progresso do download nesse componente e um contador de porcentagem. Que chique, hein?
Para isso, no evento OnWorkBegin
do componente TIdFTP
, implemente o código abaixo, responsável por ajustar o preenchimento da progress bar conforme o tamanho da atualização:
1 |
ProgressBar1.Max := FnTamanhoTotal div 1024; |
E, no evento OnWork
, atualizaremos a progress bar enquanto a transferência do arquivo estiver em andamento:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
procedure TForm1.IdFTP1Work(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); var lTamanhoTotal, lTransmitidos, lPorcentagem: real; begin if FlTamanhoTotal = 0 then Exit; Application.ProcessMessages; // obtém o tamanho total do arquivo em bytes lTamanhoTotal := FlTamanhoTotal div 1024; // obtém a quantidade de bytes já baixados lTransmitidos := AWorkCount div 1024; // calcula a porcentagem de download lPorcentagem := (lTransmitidos * 100) / lTamanhoTotal; // atualiza o componente TLabel com a porcentagem Label1.Caption := Format('%s%%', [FormatFloat('##0', lPorcentagem)]); // atualiza a barra de preenchimento do componente TProgressBar ProgressBar1.Position := AWorkCount div 1024; end; |
Agora, sim, estamos prontos! Hora de fazer toda essa mágica funcionar.
No evento de clique do botão, utilizaremos todos os métodos criados acima para processar a atualização:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
procedure TForm1.BitBtn1Click(Sender: TObject); var lNumeroVersaoLocal, lNumeroVersaoFTP: smallint; begin if not ConectarAoServidorFTP then Exit; lNumeroVersaoLocal := ObterNumeroVersaoLocal; lNumeroVersaoFTP := ObterNumeroVersaoFTP; if lNumeroVersaoLocal < lNumeroVersaoFTP then begin BaixarAtualizacao; DescompactarAtualizacao; AtualizarNumeroVersao; ShowMessage('O sistema foi atualizado com sucesso!'); end else ShowMessage('O sistema já está atualizado.'); end; |
Para fazer um teste, é simples: no FTP, faça o upload do arquivo “Atualizacao.rar” (executável compactado) e incremente o número da versão no arquivo “VersaoFTP.ini” (por exemplo, de “1.0.0” para “1.0.1”). Agora é só clicar no botão de atualização e aguardar o processo!
Houve algum problema ou dificuldade na implementação do código acima? Fique tranquilo! Clique neste link e baixe um exemplo dessa funcionalidade (com alguns aprimoramentos) desenvolvido em Delphi XE7. Mesmo assim, na terceira e última parte dessa série de artigos, apresentarei algumas ressalvas, dicas e observações que talvez possam esclarecer possíveis dúvidas sobre essa funcionalidade.
Espero vocês na próxima semana para fecharmos esse assunto com chave de ouro!
Grande abraço!
Confira as outras partes desse artigo:
[Delphi] Atualização Automática – Parte 1
[Delphi] Atualização Automática – Parte 2
[Delphi] Atualização Automática – Parte 3
E para atualiza o banco de dados junto com o executavel como Faria. Já procurei artigo nesse sentido mas nunca achei.
Olá, Joabe, tudo certo?
Ótima pergunta! Na verdade, eu vou tratar essa questão na terceira parte dessa série.
Mesmo assim, adiantando, depende de qual banco de dados você está utilizando. No meu caso, como uso Firebird, executo uma linha de comando da ferramenta isql para rodar os scripts no banco de dados durante a atualização. Para outros bancos, o mecanismo de atualização provavelmente será diferente.
Por conta dessa necessidade, também já encontrei desenvolvedores que criaram um “atualizador do banco de dados”, configurado para ser executado junto com a atualização do executável.
Abraço!
Show. Parabens pelo tutorial. Aguardando ansiosamente o terceiro artigo.
Olá, Abraão!
Muito obrigado pelo feedback! A terceira parte será publicada na próxima semana!
Abraço!
Fala André! Parabéns pela segunda parte do post! Muito bom, bem explicado e ilustrado. Infelizmente estou com um probleminha… kkkkkkk
Can’t open atualizacao/VersaoFTP.ini: No such file or directory
Esqueci de algum detalhe? O seu exemplo de projeto funciona perfeitamente, até mesmo compilado no Xe2. Copiei e colei as funções para ObterNumeroVersaoFTP e ObterNumeroVersaoLocal. Para ter certeza que não foi erro de digitação.
Obrigado, no aguardo.
Boa tarde. Desculpa André. Erro meu, já está tudo ok! Obrigado, ótimo post!!
Opa, Jessé, já conseguiu identificar o erro?
Estava faltando o arquivo “VersaoFTP.ini” na pasta do FTP, não é? 🙂
Continue seguindo o tutorial. Se houver mais algum problema, me informe!
Abraço!
Boa tarde André! Realmente faltava o arquivo, muito descuido meu! kkk
Então, fiz algumas alterações apenas na forma de uso, não alterei o código. No meu computador o esquema funciona perfeitamente, Já na máquina dos clientes num primeiro momento a atualização não saiu de 0%. E na segunda tentativa, quando ele baixa o arquivo não termina o processo, ele cria um Sistema_Backup, mais não descompacta e executa a nova versão. Praticamente fica um executável corrompido. Ai tenho que ir na máquia descompactar o Atualizacao.rar e substituir o executável corrompido do usuário.
Apresenta o erro: “Invalid argument to date encode.”
A .dll e o 7.exe estão na pasta raiz de todos os usuários junto com o sistema.
O quê poderia ser? Pois na minha máquina atualiza perfeitamente.
Entendi, Jessé!
Vou entrar em contato com você. Acho que é apenas questão de configuração!
Abraço!
Prezado André,
Acompanho sei site a algum tempo e gostaria de agradecer pelos excelentes artigos, exemplos em Delphi e dicas em geral.
Quanto a implementação da atualização automática, gostaria de saber no próximos artigos, como atualizar outros arquivos além do exe. (como uma dll por exemplo) e como os colegas acima já lembraram, como seria sua solução para um DB Firebird.
Abraço.
Olá, Marcos, tudo certo?
Primeiramente, agradeço por acompanhar e blog e também pelo feedback!
Bom, Marcos, em um dos meus projetos, tenho justamente essas 3 necessidades: atualizar o executável, copiar alguns arquivos de configuração e executar alguns scripts no banco de dados.
Para copiar os arquivos, utilizo um arquivo BAT com instruções em DOS, como, por exemplo:
Para executar os scripts, utilizo a linha de comando abaixo da ferramenta isql do Firebird:
Tecnicamente, a aplicação realiza os seguintes passos:
– Baixa e descompacta a atualização, que contém o executável, o arquivo BAT, os arquivos a serem copiados e o script;
– Copia o executável;
– Executa o arquivo BAT, copiando os arquivos que vieram com a atualização;
– Executa a linha de comando do isql para rodar os scripts;
Para que isso funcione, claro, o arquivo BAT e o script devem sempre estar com um nome padrão para que a aplicação possa encontrá-los durante a atualização. No meu caso, optei por “Atualizacao.bat” e “Script.sql”.
Na prática, confira o corpo do método que processa a atualização:
Abraço!
Muito bom (^_^) aguardamos a próxima parte, parabéns pelo artigo.
Obrigado, André!
Abração!
Parabéns meu amigo, ótimos artigos.
Valeu, Charles! 🙂
Utilizo Delphi 7 (Utilizo o Indy 10.0.52) , e ao abrir o programa da a seguinte mensagem de erro:
Error reading IdFTP1.IPVersion: Property IPVersion does not exist
Olá, Jolielson, tudo bem?
O exemplo do artigo foi desenvolvido em Delphi XE7, então há propriedades de alguns componentes que não existem em versões anteriores.
Neste caso, eu sugiro que a implementação seja feita passo a passo conforme orientado no artigo, ok?
Abraço!
Boa noite André, fiz um porte do seu app para Lazarus e gostaria de compartilhar com você para análise e se quiser, para divulgar com os demais usuários do seu site. As poucas alterações que fiz estão anotas no fonte. Eu estava procurando algo assim para os meus projetos, principalmente sobre como utilizar a partir de um site que oferta o acesso ftp gratuito :).
No aguardo…
Abraço!
Olá, Wilton, tudo certo?
Opa, claro que pode compartilhar! Com certeza vai ajudar muitos desenvolvedores!
Envie um e-mail para “[email protected]” com o projeto para que eu possa compartilhá-lo aqui!
Obrigado pela colaboração! Abraço!
Olá André, tudo bom?
Sou novato no assunto programação
Fiz o seu tuto e deu quase tudo certo. A única coisa que não estou conseguindo é descompactar o arquivo baixado do site através da linha de comando. O que será que pode estar errado?
Obrigado pelas dicas!
Olá, Ruddy, tudo certo?
Talvez há um erro de sintaxe na linha de comando do 7z. A sintaxe correta é:
A opção “-o” fica junto com o nome do arquivo descompactado (sem espaços).
Para testar, você pode executar essa linha via prompt de comando do Windows. Dessa forma será mais fácil identificar o erro.
Além disso, existe a possibilidade da aplicação não estar encontrando os arquivos do 7z (7z.exe e 7z.dll). Lembre-se de colocá-los na mesma pasta em que está a aplicação.
Obrigado pela visita!
Abraço!
Olá, boa noite
Como disse, ainda sou novato no assunto. Estava declarando as function e procedure no private, assim que mudei para public, consegui descompactar. Me ajudou muito, fiz apenas um ajuste para o programa encerrar e reiniciar automaticamente após atualizado
Obrigado!
Opa, que bom que resolveu, Ruddy!
Boa sorte no seu aprendizado com programação! Abraço!
Porque esse comando não está dando certo ?
ShellExecute(0, nil, ‘7z’, PWideChar(‘ e -aoa ‘ +
sNomeArquivoAtualizacao+’-o’ +ObterDiretorioDoExecutavel), ”, SW_SHOW);
Olá, Joabe, tudo bem?
Identifiquei que falta um espaço antes do “-o”. Vide o exemplo do artigo.
Se mesmo assim funcionar, experimente rodar este comando pelo prompt do DOS e visualizar a mensagem de erro.
Abraço!
Boa tarde André, tudo bem? Eu fiz esse procedimento no Delphi 2007 e funcionou perfeitamente. Fiz a mesma coisa em uma outra aplicação em Delphi XE7 porém está dando um erro que não consigo até agora identificar o problema. Na hora de baixar o arquivo .rar ele está baixando para o diretório correto porém quando vou abrir o arquivo dá a seguinte mensagem : Final inesperado do arquivo.
Ele gera o arquivo “executavel_bkp.exe” mas o “executavel.exe” fica com o tamanho de 0 bytes e não é possível abrir.
Segue o código nessas partes:
Poderia verificar, por favor? Obrigado.
Olá, Carlos, tudo bem?
O arquivo compactado parece estar corrompido. Isso geralmente ocorre quando tenta-se compactar o executável enquanto ele ainda está em uso.
Mesmo assim, vou entrar em contato com você, ok?
Abraço!
André, boa tarde. Fiz o meu atualizador e está funcionando certinho, mas tem um erro aqui:
EZeroDivide with message ‘Floating point division by zero’
Vi que esse erro é na hora de mostrar a porcentagem do download. Usando o Delphi 7!
Olá, Guilherme!
Certifique-se de que a instrução abaixo está no início do evento OnWork do IdFTP:
Se mesmo assim o problema persistir, envie a unit para “[email protected]”.
Abraço!
André, consegui!
Achei o erro:
FnTamanhoTotal := IdFTP1.Size(‘atualizacao/Atualizacao.rar’);
Consertei o caminho do arquivo e deu certo! =D
Mas agora um probleminha:
Ele só chega até 98%, e já dá a mensagem kkkkkkk
O que pode ser?
Olá, Guilherme!
Conforme orientado por e-mail, uma das soluções é utilizar o evento OnWorkEnd para preencher os 100% da porcentagem.
Abraço!
Quando eu deixo meu programa na área de trabalho funciona perfeitamente, mas se eu colocar em outro local como Arquivos de Programas (x86) ele não descompacta.
Olá, João Pedro, tudo bem?
Este problema está relacionado com a segurança do sistema operacional. Por padrão, o Windows não permite a criação/alteração de arquivos dentro da pasta “Arquivos de Programas” sem a intervenção do usuário ou sem os privilégios de administrador. Para evitar esse evento, muitos programadores geralmente configuram a pasta da aplicação no C:\.
Abraço!
Boa Noite André.
Primeira mente quero agradecer todo o seu trabalho. Me ajudou e muito.
Porém tenho um pequeno problema: eu quero descompactar todos os arquivos que estão dentro da pasta Atualização.
Qual seria a linha de comando?
Amigo André, no lugar do 7z para compactar, poderia usar a função ZLib do Delphi. Eu acharia melhor.
Olá, Florisvaldo!
Em breve pretendo refazer essa série de artigos sobre atualização automática utilizando recursos mais modernos do Delphi. Entre eles, a biblioteca
System.Zip
, que traz a classeTZipFile
para trabalhar com compactação de arquivos.Abraço!
Olá, André. Gostaria de agradecer por este artigo, pois irá facilitar muito a atualização dos meus sistemas, deixando para o próprio cliente fazer isto, muito fácil.
Porem me surgiu uma duvida. Eu fiz de acordo com o que você passou e deu tudo certo. Mas depois eu fiz isto mais dinâmico e reaproveitável. Criei minha class TFTP e dentro dela tem uma variável do tipo TIdFTP onde fiz todos os processos. Também deram todos certos, mas agora não estou conseguindo atualizar meu progressBar pois não sei como informar um evento direto na classe nunca utilizei isto. Como que eu devo fazer?
Olá, Messias, boa noite!
Criar uma classe exclusiva para trabalhar com o FTP, assim como você fez, é o mais adequado.
Para atualizar a barra de progresso, você precisa injetar o
TProgressBar
dentro da classe TFTP. Pode ser pelo construtor…… ou por propriedade:
Com a referência da barra de progresso dentro da classe, você pode manipular o seu status (incrementando a propriedade Position).
Abraço!
Olá. Estou tentando fazer update de teste mas está dando o erro Can’t open atualizacao/VersaoFTP.ini: No such file or directory. Já coloquei em tudo que é lugar no servidor ftp o arquivo .ini e o .rar. Pode me ajudar?
Olá, Victor, tudo bem?
Experimente adicionar uma barra no início do endereço no comando GET do TIdFTP:
Fico no aguardo do seu retorno.
Abraço!
Consegui resolver o problema do arquivo corrompido. Na configuração padrão do IdFTP o tipo da propriedade TransferType é ftASCII.
Para não dar erro deve-se mudar para ftBinary.
Com isso ele baixa o arquivo e extrai corretamente.
Abraços
Obrigado pela contribuição, Carlos!
Grande abraço!
André, boa Noite. Vi a matéria bem explicada mas estou com dificuldade técnica. Estou com o erro Can’t open atualizacao/VersaoFTP.ini: No such file or directory.
Criei esta pasta no localweb.com, consigo fazer download do arquivo de forma manual mas quando tento executar pelo Delphi ocorre o erro indicado. Já verifiquei tudo que foi informado nos post acima e não cheguei à conclusão.
No provedor está no seguinte local (2 para ser mais exato):
1 – public_ftp/atualizacao
2 – public_html/atualizacao
Mas o erro dá na function ObterNumeroVersaoFTP na linha 112:
Isto é, ele conecta, loga, mas não encontra o arquivo. Já está ftBinary, mas sem resultado.
Fico grato se puder dar uma força. Se precisar de mais dados posso passar.
Olá, Ailton!
Vou entrar em contato com você para resolvermos este problema.
Abraço!
André Celestino, boa Tarde. Consegui resolver o problema, foi tremendo. Usei o FileZilla para mostrar o caminho e percebi que o localhost colocou minha pasta de forma que mesmo mostrando na tela o caminho “public_html/atualizacao”, ele considerava “public_html” apenas. Então entrei em contato com a localhost e foi detectado e corrigido este erro. Era na minha conta do localhost, portanto, agora com o caminho corrigido, a atualização passou a funcionar perfeitamente.
Parabéns pela matéria (aula) e obrigado pela atenção prestada.
Que bom que conseguiu resolver, Ailton.
Problemas desse tipo são comuns em serviços de hospedagem. Basta uma pequena configuração para funcionar.
Abraço!
Bom dia André, este programa é um programa secundário para atualizar um outro, certo? Existe algum jeito de fazer um programa atualize ele mesmo?
Olá, Jorge!
Essa funcionalidade pode ser codificada tanto em um atualizador automático isolado quanto no próprio programa principal. O código é o mesmo!
A diferença é que, caso esteja no programa principal, você terá que forçar a finalização do programa ao concluir da atualização, de forma que o programa seja reaberto já com as atualizações baixadas.
Para reiniciar a aplicação, você pode usar este código:
Abraço!
Muito boa esta publicação, aprendi muito com ela.
Parabéns e Obrigado.
Obrigado, Geraldo!
Abração!
Boa Tarde, poderia me ajudar?? Estou com problema nessa linha, não esta descompactando.
Obrigado.
Já estamos nos falando por e-mail, Felipe!
Ola André, gostaria de saber como faço para baixar pastas ou mais arquivos junto com o exe ?? obrigado!
Olá, Wanderson, tudo bem?
A princípio, basta adicionar as pastas e os outros arquivos dentro do arquivo compactado (Atualizacao.rar).
Em um dos meus projetos, por exemplo, geralmente adiciono um script SQL e um arquivo de configuração junto com o EXE no arquivo compactado.
Abraço!
Bom dia, show, boa ideia, ai descompacta e substitui os diretórios 👏🏻👏🏻👏🏻👏🏻👏🏻👏🏻
Isso mesmo! =D
Opa André, parabéns pelo material. Aqui pra mim não estou conseguindo, o que posso estar fazendo de errado…
Botao para conectar:
Botao para realizar o upload:
Ele sempre da o erro de connection closed gracefully, mas no tratamento ele não mostra, se eu testo a conexão, ele diz que não está conectado e também não copia o arquivo para o servidor, o que fiz de errado… me ajuda pf….
Olá, Márcio!
O código parece estar correto.
Experimente adicionar essa linha antes de conectar:
Espero que ajude.
André, gostaria de agradecer pelo excelente blog por esse tutorial incrível. Parabéns!
Estou com um problema que é a descompactação do arquivo, eu renomeio, excluo, porém, não consigo descompactar!
Agradeço se puder me ajudar.
Obrigado!
Olá, Humberto!
Você está tentando descompactar com o 7-Zip (7z.exe)? Se for, este é o comando:
7z e -aoa Arquivo.rar -oC:\Atualizacao
Note que “-o” fica junto com o diretório de descompactação, ou seja, não há espaços.
Quando há problemas com o 7-Zip, eu sempre oriento o pessoal a rodar o comando pelo prompt do DOS para descobrir o erro. Se o comando funcionar, o erro está na aplicação Delphi; caso contrário, o erro está na sintaxe do comando.
Abraço!