FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Descargar y actualizar un EXE
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Descargar y actualizar un EXE
Posted: Wed Mar 27, 2019 02:48 PM
Estimados:
Tengo un programa que se actualiza, seg煤n si la version que tiene el cliente esta o no actualizada, haciendo click en un formulario de actualizacion, que el cliente elije ejecutar.
Para ello, descargo el programa actualizado desde un ftp.
Para ello, utilice una funcion que escribio Biel en su blog (http://bielsys.blogspot.com/2009/04/act ... ca-de.html) hace ya mucho tiempo.
El problema me surge ahora, en algunas maquinas con Windows 10 (no en todas), descarga el programa, pero no renombra el exe descargado por el actual.
Alguien le ha pasado o tiene alguna solucion alrtenativa
Este es mi codigo:
Code (fw): Select all Collapse
聽 聽cFile := "aplicacion.exe"
   cDirLocal := hb_curdrive()+":\"+CurDir()
聽 聽IF ConectaServerFtp() 聽 聽 聽 
聽 聽 聽 聽aFiles:=oFtp:ListFiles('public_html/descargas/aplicacion.exe')
聽 聽 聽 聽IF LEN(aFiles) = 0
聽 聽 聽 聽 聽 MsgStop("Error de descarga al comparar!!","ERROR")
聽 聽 聽 聽 聽 oFtp:Close()
聽 聽 聽 聽 聽 RETURN .F.
聽 聽 聽 聽ENDIF
聽 聽 聽 聽nSize := aFiles[1,2] 聽 聽 聽 
聽 聽 聽 聽IF nSize = 0
聽 聽 聽 聽 聽 MsgStop("Error de descarga al bajar!!","ERROR")
聽 聽 聽 聽 聽 oFtp:Close()
聽 聽 聽 聽 聽 RETURN .F.
聽 聽 聽 聽ENDIF 聽 
聽 聽 聽 聽oFtp:DownLoadFile( ".\tmp.exe", 'public_html/descargas/aplicacion.exe' ) 
聽 聽 聽 聽ELSE 
聽 聽 聽 聽oFtp:Close()
聽 聽 聽 聽MsgStop("Fallo la conexion...","Error")
聽 聽 聽 聽RETURN nil 
聽 聽ENDIF 聽 聽
聽 聽oFtp:Close()
聽 聽IF FSIZE(".\tmp.exe") = nSize .AND. nSize > 0
聽 聽 聽 MsgWait("Reinciciando la aplicacion","Espere",1) 聽 聽 聽 
聽 聽 聽 ResToFile()
聽 聽 聽 WinExec( cDirlocal+'\ActVer.exe '+ cFile ,0)
聽 聽 聽 PostQuitMessage(0)
聽 聽 聽 QUIT
聽 聽 聽 ELSE 
聽 聽 聽 MsgStop("Error de descarga al renombrar!!","ERROR")
聽 聽 聽 QUIT
聽 聽ENDIF 聽 
RETURN .t.


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

#pragma BEGINDUMP
#include "Windows.h"
#include "hbApi.h"
HB_FUNC( RESTOFILE )
{
HRSRC res=FindResource(NULL,"ACTVER",RT_RCDATA);
LPDWORD bytesWritten;
int size=SizeofResource(NULL,res);
HGLOBAL hRes=LoadResource(NULL,res);
unsigned char *pRes=(unsigned char *)LockResource(hRes);
HANDLE hFile=CreateFile("ACTVER.EXE",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
WriteFile(hFile,pRes,size,&bytesWritten,NULL);
CloseHandle(hFile);
}
#pragma ENDDUMP

El codigo en C de ACTVER.EXE es el siguiente:
Code (fw): Select all Collapse
#include "stdio.h"
#include "windows.h"

int main( int argc, char *argv[])
{
Sleep(700);
DeleteFile( argv[1]);
rename( "tmp.exe",argv[1]);
WinExec(argv[1],argc);
return EXIT_SUCCESS;
}

Gracias de antemano
Posts: 1515
Joined: Thu Oct 30, 2008 02:37 PM
Re: Descargar y actualizar un EXE
Posted: Wed Mar 27, 2019 03:05 PM
Alguien le ha pasado o tiene alguna solucion alrtenativa


El mundo del renombramiento de ejecutables es todo una odisea. Lo que antes no renombraba ahora lo hace y al rev茅s.

Mi solucion:

1 - Suponiendo que tu programa se llama aplicacion.exe, al descargar desde el ftp descargalo a帽adiendole un sufijo unico, por ejemplo aplicacion_27032019_160200.exe.
2 - Luego, al arrancar el aplicacion.exe, justo al entrar, localiza que ejecutable aplicacion_*.exe es m谩s reciente y lanzalo, cerrando al llamador con un Quit y
3 - al entrar con este ejecutable renombrado intenta:
a) Borrar ejecutables renombrados antiguos
b) COPY FILE aplicacion_27032019_160200.exe TO aplicacion.exe

Con estos dos ultimos pasos se logra mantener como ejecutable aplicacion.exe y la carpeta limpia de renombrados aplicacion_*.exe
Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Re: Descargar y actualizar un EXE
Posted: Wed Mar 27, 2019 04:22 PM

Gracias por responder hmpaquito!
De la forma que lo hago, el exe principal es que lanza tanto la descarga y luego lanza a ACTVER.EXE que es el que se encarga de renombrar y volver a lanzar al ejecutable principal.
Cuando lo descargo lo grabo con un nombre que no es 煤nico, lo grabo siempre como TEMP.EXE , pero inmediatamente despues el programa ACTVER renombra ese exe como aplicacion.exe (espera 7 segundos) y lanza nuevamente aplicacion.exe. De esta manera el cliente solo ve que el programa se reinicia... Pero no hay un segundo programa Fivewin.
Igualmente por lo que me decis, voy a probar descargarlo con un nombre unico, y en el ACTVER cambiar el borrado por un renombrado del exe original

Posts: 147
Joined: Tue Oct 11, 2005 08:22 PM
Re: Descargar y actualizar un EXE
Posted: Thu Mar 28, 2019 01:06 PM

Hola

Yo lo tengo funcionando de la siguiente manera:

Bajo el nuevo ejecutable de un ftp a una carpeta llamada "Descargas" dentro de la carpeta de mi aplicaci贸n, despu茅s llamo desde mi aplicaci贸n a otro programa que es el que hace la actualizaci贸n del ejecutable:

Verifico que exista el nuevo ejecutable y si existe, llamo al programa que actualiza:

FUNCTION Actualizar()

If !MsgNoYes( "El sistema se actualizar谩, est谩 usted seguro de realizar este proceso?","Confirme" )
Return NIL
EndIf

ShellExecute( 0, , "actualiza.exe", , NIL, 3 )

oVentPrin:bValid := { || NIL }

PostQuitMessage( 0 )
Quit

Return NIL

Y este es el c贸digo del programita que hace la actualizaci贸n del ejecutable y lo lanza de nuevo:

FUNCTION Actualiza()

SysWait( .7 )

If !File( ".\Descargas\" + "SICCE.EXE" )
MsgStop( "No se encuentra el archivo para actualizar","Error" )
WinExec( "sicce.exe", 0 )
PostQuitMessage( 0 )
Quit
EndIf

If File( "SICCEOLD.EXE" )
FErase( "SICCEOLD.EXE" )
EndIf

FRename( "SICCE.EXE", "SICCEOLD.EXE" )
MoveFile( ".\Descargas\" + "SICCE.EXE", ".\" + "SICCE.EXE" )

MsgInfo( "Sistema actualizado con 茅xito","Aviso" )
WinExec( "sicce.exe", 0 )
PostQuitMessage( 0 )
Quit

Return NIL

A mi me funciona sin problemas.

Saludos !

Eduardo Borond贸n Mu帽iz

Posts: 1344
Joined: Wed Nov 16, 2005 09:14 PM
Re: Descargar y actualizar un EXE
Posted: Thu Mar 28, 2019 03:01 PM
Hola Eduardo!
Gracias por tu inter茅s y por tu sugerencias.
Al final hice algo parecido a lo que vos me decis, y a la propuesta de hmpaquito, pero desde dentro del ejecutable ACTVER.EXE que es un programa C que "guardo" dentro del recurso, y lo extraigo para la ocacion.
Asi quedo:
Code (fw): Select all Collapse
#include "stdio.h"
#include "windows.h"

int main( int argc, char *argv[])
{
Sleep(700);
DeleteFile( "viejo.exe");
rename( argv[1],"viejo.exe");
rename( "tmp.exe",argv[1]);
WinExec(argv[1],argc);
return EXIT_SUCCESS;
}

Esto funciona mucho mejor, pero igual estoy teniendo un problema, o con los nombres largos de directorios, o con los permisos de Windows 10.
El programa se instala con un instalador de Inno Setup, y el usuario puede elegir la ruta donde instalarlo. Si el cliente tiene Windows 10, generalmente le propone descargarlo en Archivos de programas (x86) y la carpeta que elija (que viene por defecto con el nombre del programa).
Si el nombre de la carpeta es largo y contiene espacios, no hace bien el reemplazo. Si es corto (o si le modifico a mano el nombre de la carpeta por uno corto) el reemplazo lo hace perfecto...
Sigo investigando...
Posts: 131
Joined: Tue Dec 26, 2006 04:50 PM
Re: Descargar y actualizar un EXE
Posted: Thu Apr 04, 2019 11:13 PM
Les comparto como lo hago yo, este m茅todo lo he usado desde hace varios a帽os y nunca me ha dado problemas, independientemente de las versiones de windows en las que se ejecute (funciona desde windows 98 hasta windows 10).

B谩sicamente necesitas dos ejecutables, un ejecutable que es tu aplicaci贸n principal y uno que se encargar谩 de actualizarlo.


En mi c贸digo tengo una variable que tiene el n煤mero de versi贸n del ejecutable Tubelite.EXE, cuando quiero publicar alguna actualizaci贸n lo 煤nico que hago es cambiar el valor de esta variable y poner el mismo valor en una peque帽a DBF que solo tiene un registro, en el que guardo el n煤mero de versi贸n y un campo MEMO donde guardo una breve explicaci贸n de los cambios o mejoras realizadas, al iniciar mi programa abro ese DBF (puede ser una base de datos de cualquier tipo), la leo y comparo el valor de ese campo contra el valor de mi variable, si estos valores son diferentes le muestro un dialogo al usuario indicando que hay una actualizaci贸n, no le doy la opci贸n de que aplique o no la misma, solo le informo que se har谩 la actualizaci贸n.

Code (fw): Select all Collapse
Public cVer_loc := "3.0.0.0"



NOTA: cuando cambio el valor de la variable en mi c贸digo debo cambiar tambi茅n el valor en la base de datos, de otra manera se quedar铆a atrapado en un loop, ya que el valor en el c贸digo y en la base de datos ser铆an siempre diferentes.

Code (fw): Select all Collapse
use &dbvers shared
聽 聽goto 1
聽 聽store version to cUlt_ver
聽 聽store whatsnew to cWhats
聽 聽if alltrim(cVer_loc)#alltrim(cUlt_ver)
聽 聽 Public oDialver, oGet1v, oGet2v, oGet3v, oBtn1v
聽 聽 define dialog oDialver resource "DLGVERSION" of oVentp1 icon "icono1" font oFont1g
聽 聽 NoCloseButton(oDialver)
聽 聽 redefine get oGet1v var cVer_loc ID 1 of oDialver READONLY
聽 聽 redefine get oGet2v var cUlt_ver ID 3 of oDialver 聽READONLY
聽 聽 redefine get oGet3v var cWhats ID 5 of oDialver MEMO READONLY
聽 聽 redefine button oBtn1v ID 6 of oDialver action (nValsal:=1,updatever())
聽 聽 activate dialog oDialver center
聽 聽endif


Entonces llamo a la funci贸n "updatever()" que es realmente donde se hace la magia, esta funci贸n lo que hace son dos cosas, primero verifica que el ejecutable que har谩 la actualizaci贸n exista (en mi caso est谩 en el mismo directorio de la aplicaci贸n principal), si el archivo existe lo ejecuta WinExec('sacsupdat.exe") y se "suicida" con las instrucci贸nes
"PostQuitMessage(0)"
"__Quit()"

Code (fw): Select all Collapse
Function updatever()
聽 聽if file("sacsupdt.exe")
聽 聽 聽 WinExec("sacsupdt.exe")
聽 聽 聽 PostQuitMessage(0)
聽 聽 聽 __Quit()
聽 聽else
聽 聽 聽 ?"No se encontro el archivo de actualizaci贸n SACSUPDT.EXE. Verificalo y vuelve a intentar"
聽 聽 聽 aborta()
聽 聽endif
return


Como el archivo principal ya no esta en ejecuci贸n (puesto que ya se "mato") el ejecutable "sacsupdat.exe" solo tiene unas instrucciones para copiar el archivo tubelite.exe que esta almacenado en una carpeta compartida y sin restricciones de acceso, una vez que lo ha copiado se "suicida" tambi茅n ya vuelve a llamar al Ejecutable original

Code (fw): Select all Collapse
cFileorig:="\\192.145.1.1\update\tubelite.exe"
cRutaDest := hb_curdrive()+":\"+curdir()+"\"
copy file cFileorig) to (cRutaDest)
WinExec("tubelite.exe")
聽 聽 聽 PostQuitMessage(0)
聽 聽 聽 __Quit()

Continue the discussion