Atualizador FTP VB6

Atualizador Escrito em Visual Basic 6 usando componente Winsock, que permite a download a partir de um servidor FTP e execução de um processo de atualização.

Há cerca de 2 anos, precisei encontrar uma forma de atualizar minha aplicação (HP-SIAC - Sistema de Automação Comercial), e já possuo instalado um servidor FTP (FileZilla Server) em um notebook antigo (Celeron com 1 GB Ram).

Nota: Foi de fundamental importância a existência de um servidor local para os testes que realizei ao testar minha aplicação. Em meu servidor Ftp tenho uma maquina virtual (Vbox) com um servidor filezzila instalado. O Arquivo é grande, mas com um pouco de paciência pode ser baixado. Procure também na internet, existem excelentes tutoriais mostrando como instalar e configurar um servidor Ftp.

Inicialmente encontrei grande dificuldade em produzir um programa que, lê-se no servidor em uma determinada pasta, um conjunto de arquivos e executasse um conjunto de tarefas para atualizar os programas e dados. Mas após montar uma colcha de retalhos, com pedaços de rotinas de diversos tutoriais, conseguir chegar a este resultado que aqui apresento a vocês.

  1. O funcionamento de um servidor FTP:

    Um servidor Ftp realiza a comunicação através de uma porta (normalmente 21), onde obedece a uma série de comandos linha a linha. Para obter uma comunicação com o mesmo deverá utilizar algum componente de comunicação (o ideal é o WinSock) e após realizar o protocolo de comunicação enviar comandos (SendData), através de uma string cujo o término seja a seqüência chr(13)+chr(10).

    Ex Winsock.SendData “LIST” & vbCrLf (busca a lista de arquivos da pasta atual).

    Destaquei este artigo na internet onde é mostrado o funcionamento do FTP:

    Bem, o importante é entender que precisaremos usar dois componentes WinSock para estabelecer a comunicação completa com o servidor. O primeiro, denominado de Inet, terá a função de comunicação básica passando os comandos e recebendo as respostas do servidor. O segundo, denominado de DataR, terá a função de transferência dos dados de arquivos existentes no servidor. Utilizarei o modo passivo, é mais simples deixar que o servidor escolha as portas.

  2. O formulário Base e seus componentes:

    Vamos então, detalhar o formulário principal e os componentes utilizados para que melhor possamos entender o código do programa:

    Figura 1. Detalhando formulário
    Figura 2. Project

    Na estrutura do projeto vemos dois formulários (Altera e Atualhp). O formulário “Altera” é uma estrutura bem simples que chamo para visualizar o texto com o histórico das atualizações de meu sistema. O formulário AtualHp, (Form main) é que será o objeto principal deste artigo. É nele que está inserido o código dos eventos e procedimentos que permite a comunicação com o servidor e download dos arquivos.

    Temos também, dois módulos com funções e procedimentos públicos. O módulo “Funções”, é todo desenvolvido por mim e possui uma série de funções que normalmente utilizo em todos os meus projetos VB6 e VB.NET. Algumas destas funções detalho no meu código, para melhor esclarecimento do seu uso. No módulo ModuloShell possuo um procedimento denominado ExecCmd que substitui o comando “Shell” do Vb (não é de minha autoria). Não vou me ater a explicá-lo, pois este não é o objetivo deste artigo, apenas mostro no código sua forma de utilização e os efeitos causados no sistema.

    Nota: A estrutura do projeto com todos arquivos utilizados encontra-se disponível para download em meu site, através de meu servidor FTP. Na pasta FtpInet, você vai encontra-lo junto com uma máquina virtual com um servido Ftp já instalado. Você também irá encontrar (em outras pastas o meu aplicativo principal (Setup-Hp-Siac-V7),outros utilitários e programas utilizados por mim ao longo destes anos. Faça bom uso de todos eles. Quando for descompactado o arquivo FtpInet.zip, que contêm o projeto será criada uma pasta (Ocx_Dll), que contêm componentes externos que precisam ser registrados com o RegSvr32 do windows.
  3. O código do programa:

    O código é todo comentado. Creio que é o suficiente para que o programador o utilize, ou ainda, copie parte de seu código para aproveita-lo em seus projetos. Por outro lado, com pequenos ajustes creio que qualquer profissional da área irá se beneficiar do seu uso integral.

Option Explicit   '-------------------- Descrição das Variáveis do Sistema ---------------------- ' ' NumArq%     Numero arquivo aberto ' AllData$    Usada de forma genérica (ler os parâmetros iniciais do sistema) ' DadosRec$   Receber os dados do servidor Ftp ' Porta%      Número da porta de comunicação de dados do servidor Ftp ' Lpos%       Qtde de bytes recebidos na porta de comunicação ' RespSv$     String de Resposta do Servidor (importante para tomada de decisão) ' Temp$       Variável de uso genérico temporário ' X&,K&       Variáveis inteiras usadas nos contadores e loops de forma genérica ' TipoDow%    Armazena o tippo do download a ser realizado para tomada de decisão ' DadosOk     Variável que armazena o estado da porta de dados do servidor ' NS% -       Contador para saber o número do servidor ' Linhas()    Usado para le linhas de texto de arquivos de textos externos. ' Servidor()  Armazena o endereço dos servidores ' InetPort()  Armazena a porta usada no servidor (normalmente 21) ' User()      Armazena os Usuários ' Pass()      Armazena as passwords dos usuários ' ' ------------------------------------------------------------------------------ ' Obs: Outras variáveis são utilizadas durante os diversos processos que '      serão explicadas durante estes procedimentos. Determinei apenas 3 nós '      para os arrays que guardam os dados dos servidores pois não juguei '      necessidade para mais. ' ------------------------------------------------------------------------------ ' São usados dois componentes Winsock (DataR e Inet) um para comunicação básica ' e o outro para fazer download de dados. ' -------------------------------------------------------------------------------------- ' É importante frisar que parte destes códigos foram retirados de outras rotinas ' encontradas na internet e adaptadas as minhas necessidades. ' --------------------------------------------------------------------------------------   Dim AllData$, DadosRec$, Porta%, QtdV&, Lpos&, RespSv, Temp$, X&, K& Dim Tipodow%, DadosOk As Boolean, NS%, NumArq% Dim Linhas$(3), Servidor$(3), InetPort%(3), User$(3), Pass$(3)   Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) ' Evento Keydown do formulário '     Caso digite a tecla <esc> (codigo 27) sai do sistema '     caso digite a tecla <f8> troca o servidor (dados armazenados nos Arrays)       If KeyCode = 27 Then Unload Me     If KeyCode = 119 Then MudaServidor End Sub   Private Sub Form_Unload(Cancel As Integer) ' Saida do Form fecho os dois controles Winsocks caso estejam abertos     Inet.Close     DataR.Close End Sub   Private Sub Form_Load()    ' A Funções Pc(), OpenArq(), LeLinhas(), GravaLinha, Vlm() são de minha autoria.  ' Pc() - Separa os dados contidos em uma linha através de um delimitador  '   [ Pc (Linha, Delimitador, Posição na linha) ].  ' Vlm() - Parecido com o Val() só que analiza uma string e retorna o seu valor.  ' OpeArq() - Abre um arquivo para leitura, gravação ou update  '   [ OpenArq (Arquivo, Tipo) ].  ' LeLinhas - Le o arquivo até o seu final armazenando suas linhas na matriz  '   [ LeLinhas (NumArq, Matriz) ].  ' GravaLinha - Grava no muero do arquivo o texto [ GravaLinha (NumArq, Texto) ].  ' Outras funções estão contidas no modulo Funcoes mas seu estudo não se adequa ao  ' momento.  ' Eu as utilizo muito e é um resquicio da época em que fui programador em MUMPS  ' Coloca o formulário principal no canto superior direito da tela e seta NS=1  ' em seguida torna os botões VerfAtual e Atualiza desabilitados         Me.Top = 0: Me.Left = 0: NS = 1     VerfAtual.Enabled = False     Atualiza.Enabled = False   ' ------------------------------------------------------------------------------------ ' Como uso o atualizador para um sistema com 6 subsistemas utilizo o comando TaskKill ' para destruir as janelas dos programas caso elas estejam ligadas. Tentei fazer isso ' com API´s mas não obtive sucesso. ' ------------------------------------------------------------------------------------       Shell "taskkill /im contab.exe", vbMinimizedNoFocus     Shell "taskkill /im receber.exe", vbMinimizedNoFocus     Shell "taskkill /im pagar.exe", vbMinimizedNoFocus     Shell "taskkill /im estoque.exe", vbMinimizedNoFocus     Shell "taskkill /im vendas.exe", vbMinimizedNoFocus     Shell "taskkill /im compras.exe", vbMinimizedNoFocus     Shell "taskkill /im liberaepn.exe", vbMinimizedNoFocus     Shell "taskkill /im hp-siac.exe", vbMinimizedNoFocus       On Error Resume Next ' Caso ocorra algum erro durante este vai para o prox       ' Seto X=1 e abro o arquivo Servidores.Txt contido no dir da aplicação para leitura. ' Leio os dados contidos no arquivo e armazeno nos arrays. ' A Funções Pc(), OpenArq(), LeLinhas(), GravaLinha, Vlm() são de minha autoria.  ' Pc() - Separa os dados contidos em uma linha através de um delimitador  '   [ Pc (Linha, Delimitador, Posição na linha) ].  ' Vlm() - Parecido com o Val() só que analiza uma string e retorna o seu valor.  ' OpeArq() - Abre um arquivo para leitura, gravação ou update  '   [ OpenArq (Arquivo, Tipo) ].  ' LeLinhas - Le o arquivo até o seu final armazenando suas linhas na matriz  '   [ LeLinhas (NumArq, Matriz) ].  ' GravaLinha - Grava no muero do arquivo o texto [ GravaLinha (NumArq, Texto) ].  ' Outras funções estão contidas no modulo Funcoes mas seu estudo não se adequa ao  ' momento.  ' Eu as utilizo muito e é um resquicio da época em que fui programador em MUMPS    ' Abre arquivo para leitura armazena em NumArq o numero  ' Le todas as linhas do arquivo texto e armazena o numero de linhas em X       NumArq = OpenArq(App.Path & "\Servidores.txt", 1)     X = LeLinhas(NumArq, Linhas)           ' Le os dados contidos na matriz Linhas e as passa para os arrays individuais de ' Servidor, porta, usuario e senha       For K = 1 To X         Servidor(K) = Pc(Linhas(K), "|", 1)         InetPort(K) = Pc(Linhas(K), "|", 2)         User(K) = Trim(Crip(Pc(Linhas(K), "|", 3)))         Pass(K) = Trim(Crip(Pc(Linhas(K), "|", 4)))     Next K   ' Meu arquivo de servidores contem apenas 2 servidores. Existem Servidores de Ftp  '  Grátis. No meu caso utilizo um servidor de Ftp que está em meu escritório  ' (um notebook antigo). Meu outro servidor é da RedeHost e que é onde se encontra  ' o meu site www.hp-sistemas.com.br (servidor de hospedagem paga com Ftp)  '  '                Servidores.Txt  '                ftp16.redehost.com.br|21|·®ð©²§¥³ªµ¢|îåêëëèéã  '                hp-sistemas.dyndns-ip.com|100|¹ª­|  '  ' O usuário e senha encontram criptografados. A criptografia e descriptografia é feita  ' pela função Crip()  ' Uso a porta 100 em meu servidor, porque como de costume as operadoras bloqueiam a se  ' porta 21 para que os  ' usuários não criem servidores em suas conexões ADSLs caseiras (o meu caso).  ' Criei uma regra NAT em meu  ' roteador para que desviasse todas as comunicções que chegam pela porta 100 para o Ip de meu servidor na  ' porta 21 (porta usada para servidores FTP.       Kill App.Path & "\hp-siac-exe.exe"     NomeServ = Servidor(NS) & ":" & InetPort(NS)  ' -------------------------------------------------------------------------------------  ' Por ultimo elimino o arquivo Hp-Siac-Exe.Exe (Setup da atualização de meus sistemas feito no Inno Setup  ' e coloco o nome do servidor que será utilizado na tela no Label NomeServ  ' ------------------------------------------------------------------------------------- End Sub     Private Sub Form_Activate()   ' No evento Form Activate Verifico o estado da conexão caso esteja fechada executo o procedimento de conexão       If Inet.State = 0 Then CmdConecta_Click End Sub     Private Sub CmdConecta_Click()   ' Verifico o estado da conexão e estabeleço o protocolo, endereço servidor e porta. ' Em seguida conecto o servidor e coloco a variável DadosRec="" ' A verificação do processo de conexão se dará pelo evento Inet Connect.       If Inet.State = 7 Then Exit Sub ' Caso o estado 7 (conectado) sai do procedimento     Inet.Protocol = sckTCPProtocol     Inet.RemoteHost = Servidor(NS)     Inet.RemotePort = InetPort(NS)     Inet.Connect     DadosRec = "" End Sub   Private Sub Inet_Connect()   ' É importante que o programador que esteja lendo estas observações tenha uma noção dos comandos  de um servidor ' FTP. Aconselho tambem que instale um servidor FTP em uma máquina de sua rede para fazer os testes ' (eu uso o  FileZilla Server que é uma excelente opção), procure na internet que irá encontrar bons tutoriais de ' como instalar e configurar o FTP Server. ' O comando DoEvents no início faz com que o usuário possa interagir com o Form mesmo que ele esteja ' processando uma conexão. Isto permite por exemplo que o usuário tente mudar a conexão para tentar ' outro servidor. ' O Evento Connect só ocorre se houver uma resposta do servidor diferente de 0 (zero). o que significa ' que houve conexão ou que a mesma está em progresso. Caso esteja conectado (7), habilito os botões ' CmdConecta, VerfAtual, Atualiza e coloco a cor verde no label Status com a mensagem Conectado. ' Em seguida executo os procedimento EnvCmd Que enviam: ' O nome do usuário; "USER" ' A senha do usuário; "PASS" ' e a troca do diretório para "atual" (é neste diretório dos Ftps que se encontram mesus arquivos); "CWD" ' Caso não ocorra a conexão mostra no status o estado da mesma em cor vermelha que é a cor default ' do componente. ' Caso ocorra um erro durante a conexão será disparado o evento Inet Error e será dado uma mensagem       Status = "Conectando..."     DoEvents     If Inet.State = 7 Then         CmdConecta.Enabled = False         VerfAtual.Enabled = True         Atualiza.Enabled = False         VisuTxt.Enabled = False         Status.ForeColor = &HFFFFC0 ' cor verde         Status = "Conectado"         EnvCmd "USER", Trim(User(NS))         EnvCmd "PASS", Trim(Pass(NS))         EnvCmd "CWD", "atual"     Else         Status = "Estado da conexao: " & Inet.State     End If End Sub       Private Sub VerfAtual_Click()   ' Dimensiono as varáveis Num e Linha que guardarão o numero do arquivo e a linha lida usando a função OpenArq. ' Em seguida atribuo ao label Mens (label usado no corpo do Form para passar mensagem ao usuário), o valor em ' branco e as variáveis DadosOk=false e TipoDown=1 (uso duas formas de download do Ftp 1 - dados de texto e ' 2 - dados binários. Neste caso irei fazer o download de 2 arquivos de texto. ' Em sequencia Apago do diretório da aplicação o arquivo UpdtHp.New que é um arquivo de texto de controle e ' atribuo Temp="" (esta variável é usada no evento DataR DataArrival para armazenar os dados retornados no ' de dados de texto.       Dim Num%, Linha$     Mens = ""     DadosOk = False     Tipodow = 1   ' O procedimento ExecCmd substitui o comando Shell. A sua utilização se explica pois o Shell é um comando ' assincrono, ou seja, não possuo um controle de quando terminou a execução do comando enquanto o procedimento ' ExecCmd é sincrono e o sistema aguarda a execução completa do comando externo. ' Não é de minha autoria e infelizmente não sei o Autor para colocar os devidos créditos.       ExecCmd "del c:\hp-siac\updthp.new /f"     Temp = ""       ' Usando o Procedimento EnvCmd, envio os comandos "PASV" entrar no modo passivo (ideal para download) e "RETR" ' para ler o arquivo no servidor. O retorno virá na variável Temp com o texto arquivo que irei gravar no dire- ' tório da aplicação e mostrar no label Mens as atualizações disponíveis do sistema. ' Em seguida usando a mesma sequencia de comando leio o arquivo Alteracoes.txt onde tenho um texto com o histó- ' rico das alterações do sistema.       EnvCmd "PASV"     EnvCmd "RETR", "updthp.new"     Num = OpenArq("c:\hp-siac\updthp.new", 2)     GravaLinha Num, Temp     Mens = Temp     Temp = ""     EnvCmd "PASV"     EnvCmd "RETR", "Alteracoes.txt"     Num = OpenArq("c:\hp-siac\alteracoes.txt", 2)     GravaLinha Num, Temp   ' Envio o comando "size" para pegar o tamanho do arquivo que irei fazer o download (hp-siac-exe.exe) e em segui- ' desabilito o botão VerfAtual e Habilito o Atualiza e VisuTxt       EnvCmd "size", "hp-siac-exe.exe"     VerfAtual.Enabled = False     Atualiza.Enabled = True     VisuTxt.Enabled = True End Sub   Private Sub Atualiza_Click() ' Dimensiono uma variável para data do sistema alimento com a data do computador. ' Primeiro verifico a existência do arquivo Update.Txt no diretório c:\hp-siac (diretório de minha aplicação). ' Caso não exista efetuo os procedimentos de atualização. ' Caso leio a primeira linha dos arquivos UpdtHp.new e Update.txt (que após a atualização ficam iguais), para ' verificar a data do arquivo e se o sistema já está atualizado. Caso esteja saio da atulização dando a ' mensagem "O seu sistema já esta atualizado !".       Dim Data1 As Date, Data2 As Date, Num%, Ql%, Plin1$, Plin2$     If Dir("c:\hp-siac\Update.txt", vbArchive) <> "" Then         Num = OpenArq("c:\hp-siac\UpdtHp.new", 1)         Ql = LeLinhas(Num, Plin1, 1)         Num = OpenArq("c:\hp-siac\Update.Txt", 1)         Ql = LeLinhas(Num, Plin2, 1)         If DateValue(Pc(Plin1, "#", 2)) <= DateValue(Pc(Plin2, "#", 2)) Then             MsgBox "O seu sistema já esta atualizado !", 48             Exit Sub         End If '   do contrário significa que o sistema está desatualizado. Grava o ceonteudo de Mens em Update.txt     Else         Num = OpenArq("c:\hp-siac\Update.Txt", 2)         GravaLinha Num, Mens     End If   ' Desabilita o botão Atualiza torna vísivel a barra de progresso do download e seu valor zero exibe a mensagem ' "Fazendo download do arquivo...", abre o arquivo no modo binário, posiciona o contador de bytes (Lpos=1), ' Estabelece o Tipo de download (tipodown=2) e envia os comandos de download do arquivo. A partir daqui o con- ' trole passa para o evento DataArrival (chegada de dados).       Atualiza.Enabled = False     DadosOk = False     Pbar.Visible = True     Pbar.Value = 0     Mens = "Fazendo download do arquivo..."     Close #1     Open "hp-siac-exe.exe" For Binary As #1     Lpos = 1     Tipodow = 2     EnvCmd "PASV"     EnvCmd "RETR", "hp-siac-exe.exe" End Sub   Function EnvCmd(Comando$, Optional Arg1$, Optional Arg2$) ' Função de envio de comandos. O Servidor de Ftp processa os comandos na medida em que rece- ' o final da linha (VbCrLf) [Chr(13)+Chr(10)]. ' Alguns destes comandos podem ter até mais de dois argumentos (no meu caso só preciso de 2) ' estes comandos devem ser inseridos em uma string finalizada por (vbCrLf) e enviados com SendData. ' Em seguida fico esperando a resposta do servidor que deve vir na variável RespSv tratada no evento ' DataArrival.       Dim Linha$     If Arg1 <> "" Then Arg1 = " " & Arg1     If Arg2 <> "" Then Arg2 = " " & Arg2     Linha = UCase(Comando) & Arg1 & Arg2 & vbCrLf     RespSv = ""     Inet.SendData Linha     Do         DoEvents     Loop Until RespSv <> "" End Function   Private Sub Inet_DataArrival(ByVal bytesTotal As Long)   ' Este evento ocorre quando há uma chegada de dados pela porta do servidor (normalmente 21). Aqui é feita uma ' série de tomada de decisões conforme a resposta do servidor. Enviado ao corpo do programa através da variável ' RespSv. ' Dimensiono a Variável Parte que irá guardar a string de retorno do servidor. Nesta string as vezes contêm mais ' dados do que necessito, então preciso tratar a mesma para extrair o conteúdo necessário a tomada de decisões. ' Normalmente a resposta é um numero, o ifem e um texto (ex: "226 - Data Tranfer Ok"). ' o Label TxtLog é mostrado na parte inferior do form e traz as respostas do servidor, toda vez que alcança o ' tamanho de 1024 caracteres ele é zerado (seu conteúdo é apenas informativo).         Dim Parte$     If Len(TxtLog) > 1024 Then TxtLog = ""   ' Uso o procedimento GetData para armazenar a resposta do servidor e a função Instr() para analize do conteúdo       Inet.GetData RespSv, vbString       '  Quando é dado o comando "RETR" para fazer download de um arquivo o servidor retorna uma mensagem com ‘  o código 227 e com um texto com um número 2 bytes contendo a portas de comunicação de dados que serão usados ‘  pelo controle DataR (winsock) para fazer o download do arquivo. ‘  Neste momento o servidor Ftp abriu uma porta e está '  esperando uma conexão na mesma. Em seguida uso o procedimento Connect para conectar a esta porta. Caso a '  conexão seja feita começará o download do arquivo e o controle passará para o evento DataArrival do DataR.       If InStr(RespSv, "227 ") <> 0 Then         Parte = RespSv         Porta = (Val(Pc(Parte, ",", 5)) * 256) + Val(Pc(Parte, ",", 6)) ' 5a e 6a parte da resposta Usando "," delim.         DataR.Close                        ' Fecha a conexão caso aberta         DataR.Connect Servidor(NS), Porta  ' Conecta na porta informada     End If   ' Resposta "227" Download concluido       If InStr(RespSv, "226 ") <> 0 Then         If Tipodow = 2 Then Mens = "Download Concluido !"     End If   ' Resposta "213" Tamanho do arquivo (resposta do comando "Size")       If InStr(RespSv, "213 ") <> 0 Then         TamFile = Format(Val(Pc(Mid(RespSv, InStr(RespSv, "213") + 3, 50), vbLf, 1)), "#,###,###,###")         Pbar.Max = Vlm(TamFile)         Pbar.Min = 0     End If   ' Resposta "220" textos de comentários do servidor (sem valor lógico apaenas informativo)       If InStr(RespSv, "220 ") <> 0 Then Exit Sub     TxtLog = TxtLog & RespSv End Sub   Private Sub Inet_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)   ' Este evento ocorre se houver um erro na conexão com o servidor. Caso ocorra mostra a mensagem com o erro e ' volta o controle para o estado inicial do programa onde o usuário pode tentar trocar de servidor ou tentar ' uma nova conexão.       MsgBox "Erro: " & Number & ". Descricao: " & Description, 48     Status = "Erro Conexão": Status.ForeColor = vbRed     TxtLog = ""     CmdConecta.Enabled = True     Inet.Close     DataR.Close End Sub   Private Sub DataR_Connect() ' Mostra o estado da conexão de dados     If DataR.State = 7 Then Status = "Dados Conectados" End Sub   Private Sub DataR_DataArrival(ByVal bytesTotal As Long) ' Este evento é disparado toda vez que inicia o download de arquivo comando "RETR".     Dim buffer$     Select Case Tipodow ' case para o tipo de download     Case 1         DataR.GetData buffer, vbString ' Leitura dos dados na porta no formato string         Temp = Temp + buffer           ' Armazenamento cumulativo desta respota em Temp     Case 2         If DataR.State <> 8 Then             Dim bData() As Byte             DataR.GetData bData        ' Leitura dos dados no formato binário (byte a byte)             Put #1, Lpos, bData        ' gravação no arquivo #1 (hp-siac-exe.exe)             Lpos = Lpos + UBound(bData) + 1 ' Controle do numero de bytes recebidos             Pbar.Value = (Lpos - 1)         ' Incremento da barra de progesso             BytesRec = Format((Lpos - 1), "#,###,###,###")                                  ' Display dos bytes recebidos         End If     End Select     If Tipodow = 2 And BytesRec = TamFile Then  ' Caso o numero de bytes seja do tamanho do arquivo o download foi concluido         Close #1         DadosOk = True     End If End Sub   Private Sub Timer_Timer()   ' Como a leitura de dados acontece de forma assincrona é necessário ter a exata noção do momento em que ' o download foi concluido, em se tratando do arquivo binário (hp-siac-exe.exe), pois é um arquivo a ser ' executado para fazer a atualização do sistema. ' O evento Timer testa a variável DadosOk que só é colocada como True no momento em que o download é concluido. ' Então é feita a execução  dos diversos comandos necessários à atualização.       If Not DadosOk Then Exit Sub     ExecCmd App.Path & "\hp-siac-exe.exe /verysilent"     ExecCmd "del c:\hp-siac\Update.Txt"     ExecCmd "Xcopy c:\hp-siac\updthp.new c:\hp-siac\Update.Txt /y"     DoEvents     Mens = "ATUALIZAÇÂO EXECUTADA COM SUCESSO !!"     Timer.Enabled = False     Timer.Interval = 0 End Sub   Sub MudaServidor() ' Procedimento de mudança do servidor onde cada vez que é executado incrementa a variável NS ' e tenta conectar com o servidor       If Inet.State = 7 Then         EnvCmd "quit"                            ' Comando de saida do servidor FTP     End If     Mens = ""                                    ' Zera as variáveis e labels     Status = ""     TxtLog = ""     Inet.Close     DataR.Close     CmdConecta.Enabled = True                    ' Habilita Controles     VerfAtual.Enabled = True     Atualiza.Enabled = True     NS = NS + 1: If NS = 4 Then NS = 1           ' Incrementa NS     NomeServ = Servidor(NS) & ":" & InetPort(NS) ' Mostra o nome do servidor     CmdConecta_Click                             ' Executa procedimento de conexão End Sub   Private Sub VisuTxt_Click() ' -------------------------------------------------------------------------- ' Chama o Form Altera onde mostra o conteúdo do arquivo Alteracoes.txt ' --------------------------------------------------------------------------     Altera.Show End Sub
Listagem 1. Código completo
Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados