Jump to content
Fivewin Brasil

Atualizar versão do sistema - Win7


Geraldo (gbsilva)

Recommended Posts

Pessoal estou tendo problemas para atualizar a versão do sistema. No XP funciona normalmente, mas no Win7 dá erro, alguém faz atualização com Win7.

Uso esse código há muito tempo e apesar de meio ultrapassado funciona. Tentei modernizar um pouco e fiz uma pequena classe, mas também não deu certo no Win7.

#include "FiveWin.ch"

function Main()
local oDlg,oAnimate,oSay,oFont
local cOrigem,cFile
MsgWait("Verificando Atualizações!","GbSoftware",5)
MsgRun("Atualizando o Sistema...Aguarde","GbSoftware",;
{|| Atualiza(@cOrigem,@cFile) })
//-> Chama novamente o sistema com o executável atualizado
winexec(cFile)
return nil

Static function Atualiza(cOrigem,cFile)
//-> Pega local do novo executável (cOrigem) e nome do executável (cFile)
PegaIni(@cOrigem,@cFile)
CopiaArquivos(cOrigem,cFile)
return(.t.)

Function CopiaArquivos(cOrigem,cFile)
Local xOrigem,xDestino,lNewFile,cRota:=cFILEPATH(GETMODULEFILENAME(GETINSTANCE()))
//-> Se o arquivo existir deleta para atualizar
WaitSeconds(10) //-> Aguarda para dar tempo do executável fechar na rede
Delete file ".\"+cFile //-> Deleta executável atual
xOrigem := cOrigem+cFile //-> Define arquivo a ser copiado (local+nome)
xDestino := cFile //-> destino é o nome do novo arquivo que é o mesmo do antigo
Copy File &xOrigem To &xDestino //-> copia o novo executável
return(.t.)

Static function PegaIni(cOrigem,cFile)
local oWnd, oIni
INI oIni FILE ".\Amostra.ini"
GET cOrigem SECTION "config" ENTRY "origem" OF oIni
GET cFile SECTION "config" ENTRY "file" OF oIni
ENDINI
return nil

//----------------------------------------------------------------------------//

procedure AppSys // XBase++ requirement

return

Function Main()
local oFile
//-> instancia objeto da classe
oFile := TGbUpdate():new()
//-> metódo para identificar a origem e o executável
oFile:GetIni()
//-> mensagem e método de atualização da nova versão
MsgWait("Verificando Atualizações!","GbSoftware",3)
MsgRun("Atualizando o Sistema...Aguarde","GbSoftware",;
{|| oFile:Update() })
//-> Chama novamente o sistema com o executável atualizado
IF MsgYesNo("Atualização efetuada com sucesso"+CRLF+;
"Deseja executar o sistema (S/N) ?","Atualização de Versão")
Winexec(oFile:cFile)
ENDIF

return nil

************************************************************************************************************************
CLASS TGbUpdate
DATA root,cFile,hTime
DATA lSave

METHOD New() CONSTRUCTOR
METHOD GetIni()
METHOD Update()

ENDCLASS

METHOD New() CLASS TGbUpdate
::root := ""
::cFile := ""
::hTime := 10 //-> tempo de exibição da mensagem de verificação de atualizações (tempo para fechar o executável)

return self

METHOD GetIni() CLASS TGbUpdate
local oWnd,hIni,c

#ifdef rdd_sqllib
INI hIni FILE ".\gb_connect.ini"
GET ::root SECTION "mysql" ENTRY "origem" OF hIni
GET ::cFile SECTION "mysql" ENTRY "file" OF hIni
ENDINI

#else
c = "mysql"
hIni := HB_ReadIni( "connect.ini" )
::root := hIni[ c ]["host"]
::cFile := hIni[ c ]["user"]
#endif
return(.t.)

METHOD Update() CLASS TGbUpdate
local lRoot,lHome

WaitSeconds(::hTime)
Delete file ".\"+::cFile //-> Deleta o executável atual
lRoot := ::root+::cFile //-> lRoot é a junção do local de origem + nome do executável
lHome := ::cFile //-> lHome é o nome do executável a ser copiado
LZCopyFile(lRoot,lHome)

//-> substituida comando Copy File pela função LZCopyFile()
// Copy File &lRoot TO &lHome //-> copia o novo executável para a pasta do sistema
return(.t.)

****************************** FINAL DA CLASSE *************************************************************************

//----------------------------------------------------------------------------//
procedure AppSys // XBase++ requirement

return
//----------------------------------------------------------------------------//

Link to comment
Share on other sites

Geraldo, antes de copiar os arquivos execute esta função abaixo

SendMessage( FindWindow( 0, "coloque aqui o titulo da windows principal da aplicação" ), WM_CLOSE )

exemplo que uso com a minha aplicação:

SendMessage( FindWindow( 0, "CiaCpd - Aplicativos e Sistemas - Desde 1992" ), WM_CLOSE )

João se voce usa o actver.exe coloque esta função para continuar atualizando no win7

Daniel Segura

Link to comment
Share on other sites

Geraldo, antes de copiar os arquivos execute esta função abaixo

SendMessage( FindWindow( 0, "coloque aqui o titulo da windows principal da aplicação" ), WM_CLOSE )

exemplo que uso com a minha aplicação:

SendMessage( FindWindow( 0, "CiaCpd - Aplicativos e Sistemas - Desde 1992" ), WM_CLOSE )

João se voce usa o actver.exe coloque esta função para continuar atualizando no win7

Daniel Segura

Olá, eu utilizo actver.exe mas não uso SendMessage()... Gostaria de saber para que server esta função e onde coloca-lá, é antes de executar o actver.exe? Obgdão!!!

Link to comment
Share on other sites

Em algumas versões do windows 7, o actver.exe não trabalha direito porque o executável da aplicação demora para finalizar por diversos motivos, o que impede que ocorra a atualização. Abaixo o fonte que uso.

#include "\comp\xharbour12\include\FiveWin.ch"
// -------------------------------------------------------------------------- //
Function main(cFile)
   local cFileName , ntentativa
   syswait(1.7)
   ntentativa :=1
   if file('tmp.exe')
      while .t.
         if FErase( cFile ) == -1
            syswait(1.7)
	    SendMessage( FindWindow( 0, "CiaCpd - Aplicativos e Sistemas - Desde 1992" ), WM_CLOSE )
	    ntentativa++
            if ntentativa > 20
               nMsgBox( "Não foi possível criar o arquivo.", "Atenção" )
	       return nil
            endif
            loop
         endif
         cFileName:=cFileName(cFile)
         FRename('tmp.exe',cFileName)
         exit
      enddo
   EndIf
   WinExec( cFileName )
   PostQuitMessage(0)
   Quit
Return NIL
// -------------------------------------------------------------------------- // 
Daniel Segura
Link to comment
Share on other sites

Daniel abusando da sua boa vontade, fiquei em dúvida no seu fonte, coloquei em vermelho algumas dúvidas, como exatamente ele funciona?

É que me pareceu tão simples, talvez eu possa adaptar para o meu atualizador.

Grato,

//-> cFile seria o nome do seu executável 
Function main(cFile)
   local cFileName , ntentativa
   syswait(1.7)
   ntentativa :=1
   //-> de onde vem esse tmp.exe ? como você passa ele para a função ?
   if file('tmp.exe')
      while .t.
        //-> tenta apagar o cFile até 20 vezes 
        if FErase( cFile ) == -1
            syswait(1.7)
	    SendMessage( FindWindow( 0, "CiaCpd - Aplicativos e Sistemas - Desde 1992" ), WM_CLOSE )
	    ntentativa++
            if ntentativa > 20
               nMsgBox( "Não foi possível criar o arquivo.", "Atenção" )
	       return nil
            endif
            loop
         endif
         //-> Dúvida você não deletou o cFile? como atribui ao cFileName 
         cFileName:=cFileName(cFile)
         //-> Aqui tudo bem renomeia o tmp.exe para nome do cFileName exceto a obs anterior
         FRename('tmp.exe',cFileName)
         exit
      enddo
   EndIf
   //-> executa o arquivo
   WinExec( cFileName )
   PostQuitMessage(0)
   Quit
Return NIL
Link to comment
Share on other sites

Vamos lá,

cFile -> é o nome do executável.

tmp.exe -> é o novo executável que foi baixado do site via ftp conforme http://bielsys.blogspot.com.br/2009/04/actualizacion-automatica-de.html.

20 vezes-> é o número referente ao STRESS do dia quando falava para uma operadora de caixa atualizar o sistema e não dava certo no win7.

cFileName ->recebe o nome de um arquivo completo incluindo o caminho e devolve só o nome .

WinExec -> executa a aplicação já atualizada.

segui fielmente o exemplo do biel no link informado acima, vale fazer uso desta rotina é prático e seguro.

Link to comment
Share on other sites

  • 5 months later...

Boa noite, revivendo o tópico antigo:

Estou tentando fazer minha rotina de atualização conforme os exemplos acima, porém, ao executar, ao chamar a linha:

oInternet := tInternet():New()

Aparece a mensagem:

Cannot load WinInet.dll

Alguem sabe o motivo?

Windows 8 64 bits

Link to comment
Share on other sites

Uso assim há muito tempo e nunca tive problema com nenhuma versão do windows.

   // Verificar se existe uma versão mais recente do EXE no servidor
   cExeName := UPPER(CFILENOEXT( HB_ARGV( 0 ) ))+".EXE"
   cDirSrv := SUBSTR(ALLTRIM(cPasta), 1, RAT("\",cPasta))
   IF RIGHT(cDirSrv,1) == "\"; cDirSrv := SUBSTR(cDirSrv, 1, LEN(cDirSrv)-1) ; ENDIF
   IF EMPTY(cDirSrv) ; cDirSrv := "." ; ENDIF

   aDire := DIRECTORY(cDirSrv+"\*.EXE")
   nFile := ASCAN(aDire, {|nPos|UPPER(nPos[1])==cExeName})
   IF nFile > 0
      wdata1=aDire[nFile,3]
      wtime1=aDire[nFile,4]
   ENDIF

   aDire := DIRECTORY("*.EXE")
   nFile := ASCAN(aDire, {|nPos|UPPER(nPos[1])==cExeName})
   IF nFile > 0
      wdata2=aDire[nFile,3]
      wtime2=aDire[nFile,4]
   ENDIF

   // Descomente as 3 linhas abaixo para checar por MD5 (Comente o teste por data e hora)
 * cMd5This := HB_MD5File( cExeName )
 * cMd5That := HB_MD5File( cDirSrv+"\SISCOM.EXE" )
 * IF cMd5This != cMd5That

   // Descomente a linha IF abaixo para testar por data e hora com tolerência de 15 minutos (Comente o teste por MD5)
   IF (WDATA1 > WDATA2) .OR. (WDATA1 = WDATA2) .AND. (SECS(wtime1) > (SECS(wtime2)+SECS("00:15:00")))
      cDirAtu := CurDrive()+":\"+CurDir()
      if file(cDirAtu+"\ATUALIZA.BAT")
         ferase(cDirAtu+"\ATUALIZA.BAT")
      endif
      WritePProString("ACESSOS", "ChecarDbf", "T", ".\SISCOM.INI")
      cAtuInf := "TASKKILL /IM "+cExeName+" /F"+CRLF+;
                 "XCOPY /Y /D "+cDirSrv+"\bitmaps\*.* "+cDirAtu+"\bitmaps\"+CRLF+;
                 "XCOPY /Y /D "+cDirSrv+"\modelos\*.* "+cDirAtu+"\modelos\"+CRLF+;
                 "XCOPY /S /Y /D "+cDirSrv+"\manual\*.* "+cDirAtu+"\manual\"+CRLF+;
                 "XCOPY /Y /D "+cDirSrv+"\DLL32\*.dll "+cDirAtu+"\DLL32\"+CRLF+;
                 "XCOPY /Y /D "+cDirSrv+"\*.dll "+cDirAtu+"\"+CRLF+;
                 "XCOPY /Y /D "+cDirSrv+"\"+cExeName+" "+cDirAtu+CRLF+;
                 "START "+cExeName+CRLF+;
                 "EXIT"
      arq2 := fcreate(cDirAtu+"\ATUALIZA.BAT")
      fwrite(arq2, cAtuInf)
      fclose(arq2)
      WAITRUN( GetEnv( "ComSpec" )+" /C START "+cDirAtu+"\ATUALIZA.BAT", 0 )
      SYSWAIT(3)
   ELSE
      ferase(".\ATUALIZA.BAT")
   ENDIF

Coloque antes do seu menu principal, na função inicial (Main). Adepte aí e veja se funciona.

É claro que só vai funcionar após todos os computadores terem sidos atualizados pelo menos uma vez com a versão que contém este código.

Link to comment
Share on other sites

Obrigado Ariston, mas uma pergunta, esta sua função atualiza o executável, isso? Pergunto porque no meu caso eu quero atualizar (baixar) o instalador e depois executar o mesmo, para que faça uma nova instalação, desta forma, eu tenho um exe que vai baixar outro.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...