Page 1 of 1
Abandonar la aplicacion y correr otra
Posted:
Tue Jul 11, 2006 7:04 pm
by RodolfoRBG
Hola amigos,
Intento que de manera automatica se sustituya el EXE que estoy corriendo por uno mas reciente asi que el proceso debe hacer lo siguiente:
Abandonar la presente aplicacion y encadenarse a otra que descomprime un ZIP y que copia el EXE para que sustituya al que originalmente estaba corriendo.
Al momento, en la aplicacion original (Origen.EXE por ejemplo) pongo las siguientes instrucciones:
WINEXEC("Copiar.EXE")
QUIT
M->oWndPrin:End()
donde "Copiar.EXE" se encarga de descomprimir el zip, copiar la nueva version de "Origen.EXE" para que sustituya el "Origen.EXE" viejo y despues abandone "Copiar.EXE" y corra el nuevo "Origen.EXE".
El problema con esas instrucciones es que en efecto se encadena a "Copiar.EXE" pero no siempre abandona "Origen.EXE" y al estar activo no permite sustituirlo por el nuevo.
Alguna idea?
'chas gracias de antemano
Posted:
Tue Jul 11, 2006 8:55 pm
by Antonio Linares
Rodolfo,
Lo más sencillo es usar un fichero BAT que es el que llama a los ejecutables.
Posted:
Tue Jul 11, 2006 8:58 pm
by karinha
USE UN ARCHIVO.BAT TIPO:
STATIC lDesligaProg := .F.
LOCAL NOME_ARQ, NREGISTRO
IF lDesligaProg //-> SE .T.
MsgStop( OemToAnsi( "Prezado Usuário: " ) + CRLF + ;
OemToAnsi( "Devido ao Enorme CONSUMO DE RECURSOS do " ) + CRLF + ;
OemToAnsi( "WINDOWS, Necessito Reiniciar o Programa," ) + CRLF + ;
OemToAnsi( "Para Liberação de Memória e Recursos. " ) + CRLF + ;
OemToAnsi( "Desculpe Pelo Transtorno! É Rápido." ) + CRLF + ;
OemToAnsi( "<Click> no Botão <OK> Por Favor... " ), ;
OemToAnsi( "Aviso de Perda de Recursos do Windows. " ) )
oDbfPedf:Close()
// Cria o Arquivo de Lote Balcao.Bat no Diretório, Com as Diretrizes.
IF !FILE( "BALCAO.BAT" )
NOME_ARQ := FCREATE("BALCAO.BAT")
NREGISTRO := "@ECHO OFF" ;
+ CRLF + ;
"CLS" + ;
+ CRLF + CRLF + ;
"BALCAOW.EXE" + ;
+ CRLF + CRLF + ;
"CLS" + ;
+ CRLF + ;
"EXIT"
FWRITE( NOME_ARQ, NREGISTRO )
FCLOSE( NOME_ARQ )
ENDIF
oFont1:End()
lDesligaProg := .F.
EndDialog()
Release All
WinExec( "BALCAO.BAT", 0 )
__QUIT()
ELSE
oDbfPedf:Close()
oFont1:End()
lDesligaProg := .F.
Release All
ENDIF
Posted:
Wed Jul 12, 2006 1:13 am
by RodolfoRBG
Jovenes,
No puedo usar un archivo de lotes que llame primero al "Origen.EXE" y despues al "Copia.EXE" porque el proceso es muy eventual, no se hace cada vez que se corre "Origen.EXE".
El ejemplo de Joao para crear y correr un archivo BAT no me funciono.
Si no hay alguna instruccion para cerrar "Origen.EXE" y correr "Copia.EXE" existira alguna manera que desde "Copia.EXE" cierre "Origen.EXE"?
'chas gracias por su paciencia
Posted:
Wed Jul 12, 2006 2:55 am
by wmormar
RodolfoRBG wrote:Jovenes,
No puedo usar un archivo de lotes que llame primero al "Origen.EXE" y despues al "Copia.EXE" porque el proceso es muy eventual, no se hace cada vez que se corre "Origen.EXE".
El ejemplo de Joao para crear y correr un archivo BAT no me funciono.
Si no hay alguna instruccion para cerrar "Origen.EXE" y correr "Copia.EXE" existira alguna manera que desde "Copia.EXE" cierre "Origen.EXE"?
'chas gracias por su paciencia
Podrias probar
SHELLEXECUTE()
oWnd:END()
por ahi va la idea
Posted:
Wed Jul 12, 2006 7:39 pm
by infosys
Pienso que tu problema se solucionaria, con un programa intermedio que es llamado desde EXIT PROCEDURE....., sobre la aplicacion que vas a reemplazar, yo hago lo mismo y lo solucione de esta manera.
Posted:
Wed Jul 12, 2006 7:57 pm
by RodolfoRBG
Infosys,
De hecho el programa "Copia.EXE" es un programa intermedio que se corre desde "Origen.EXE", pero este ultimo como que no se termina de cerrar al llamar al primero.
Podrias enviarme o darme un ejemplo de como le hiciste tu?
'chas gracias.
Posted:
Thu Jul 13, 2006 12:24 am
by R.F.
Rodolfo:
Origen.EXE hace un WinExec("copia.exe") hasta aqui vamos bien. Luego el ORIGEN.EXE tiene que "suicidarse", eso lo haces con un PostQuitMessage(0) y un Quit, quedaria algo asi:
WinExec("copia.exe")
PostQuitMessage(0)
__Quit()
y luego en tu programa COPIA.EXE haces lo que tienes que hacer, y vuelves a lanzar a ORIGEN.EXE
WinExec("origen.exe")
Posted:
Thu Jul 13, 2006 2:07 pm
by Patricio Avalos Aguirre
Rodolfo:
Esta rutina me ha funciona perfectamente
funciona de la siguiente manera:
1.- Cuando instalo una actualización guardo en la carpeta update\ dos archivo, uno el ejecutable.exe y otro la update.ini, que es el siguiente
- Code: Select all Expand view
_____________________________________________________________ Sistema Administrativo Version 1.0.0
(c) copyright: Patricio Avalos Aguirre, 2005
patricio_avalos_aguirre@hotmail.com
_____________________________________________________________
[Version]
numero=1.0.19
[Revision]
;08 Julio del 2006, versión 1.0.19
;bla bla bla..
;y mas blabla
- Code: Select all Expand view
#Define DRIVELOCAL DiskName() + ":\"+Curdir()
Static oApp
procedure Main()
//mi programa bla bla bla...
return
//-----------------------------------------------------------------------
Init Procedure Inicio()
oApp := MyApp():Load()
aEval( DIRECTORY( oApp:cPathTmp + "\*.*" ), { |aFichero| fErase( oApp:cPathTmp + "\"+aFichero[1] ) } )
if VerUpdate()
PostQuitMessage( 0 )
QUIT
endif
return
//-----------------------------------------------------------------------
CREATE CLASS MyApp
VAR Usuario AS CHARACTER INIT ""
VAR Nombre AS CHARACTER INIT ""
VAR Grupo AS CHARACTER INIT ""
VAR Depto AS CHARACTER INIT ""
VAR Clave AS CHARACTER INIT ""
VAR cPathTmp AS CHARACTER INIT DRIVELOCAL + "\TEMPORAL"
VAR cPathDbf AS CHARACTER INIT DRIVELOCAL + "\DATOS"
VAR cPathUpd AS CHARACTER INIT DRIVELOCAL + "\UPDATE"
VAR cPathLocal AS CHARACTER INIT DRIVELOCAL
//impresion
VAR Factura AS CHARACTER INIT "LPT1"
VAR Boleta AS CHARACTER INIT "LPT1"
VAR GDespacho AS CHARACTER INIT "LPT1"
VAR ordenCompra AS CHARACTER INIT "LPT1"
VAR Cotizacion AS CHARACTER INIT "LPT1"
VAR GRecepcion AS CHARACTER INIT "LPT1"
VAR SaliBode AS CHARACTER INIT "LPT1"
VAR ordentrabajo AS CHARACTER INIT "LPT1"
VAR Cajadiaria AS CHARACTER INIT "LPT1"
VAR nCredito AS CHARACTER INIT "LPT1"
VAR Arriendo AS CHARACTER INIT "LPT1"
VAR Finiquito AS CHARACTER INIT "LPT1"
VAR AdsServer AS NUMERIC INIT ""
VAR AdsConnect AS NUMERIC INIT ADS_LOCAL_SERVER
VAR cVersion AS CHARACTER INIT "1.0.0"
METHOD Load()
METHOD Save()
METHOD End() INLINE ::Save()
ENDCLASS
//------------------------------------------------------------------------------------------------
METHOD Load( oDbf ) CLASS MyApp
local oIni
INI oIni FILE (::cPathLocal + "\wInvent.ini")
GET ::cPathDbf SECTION "Servidor" ENTRY "Name" OF oIni DEFAULT ""
GET ::cPathUpd SECTION "Servidor" ENTRY "Update" OF oIni DEFAULT ""
GET ::Factura SECTION "Puertos" ENTRY "Factura" OF oIni DEFAULT "LPT1"
GET ::Boleta SECTION "Puertos" ENTRY "Boleta" OF oIni DEFAULT "LPT1"
GET ::GDespacho SECTION "Puertos" ENTRY "GDespacho" OF oIni DEFAULT "LPT1"
GET ::OrdenCompra SECTION "Puertos" ENTRY "ordencompra" OF oIni DEFAULT "LPT1"
GET ::Cotizacion SECTION "Puertos" ENTRY "Cotizacion" OF oIni DEFAULT "LPT1"
GET ::GRecepcion SECTION "Puertos" ENTRY "GRecepcion" OF oIni DEFAULT "LPT1"
GET ::SaliBode SECTION "Puertos" ENTRY "SaliBode" OF oIni DEFAULT "LPT1"
GET ::ordentrabajo SECTION "Puertos" ENTRY "ordentrabajo" OF oIni DEFAULT "LPT1"
GET ::Cajadiaria SECTION "Puertos" ENTRY "CajaDiaria" OF oIni DEFAULT "LPT1"
GET ::cVersion SECTION "Version" ENTRY "Version" OF oIni DEFAULT "1.0.0"
GET ::Usuario SECTION "Usuario" ENTRY "Usuario" OF oIni DEFAULT ""
GET ::Nombre SECTION "Usuario" ENTRY "Nombre" OF oIni DEFAULT ""
GET ::AdsServer SECTION "ServerAds" ENTRY "Servidor" OF oIni DEFAULT ""
GET ::AdsConnect SECTION "ServerAds" ENTRY "TypeConnect" OF oIni DEFAULT ADS_LOCAL_SERVER
::Factura := Alltrim( ::Factura )
::Boleta := Alltrim( ::Boleta )
::GDespacho := Alltrim( ::GDespacho )
::OrdenCompra := Alltrim( ::OrdenCompra)
::Cotizacion := Alltrim( ::Cotizacion )
::GRecepcion := Alltrim( ::GRecepcion )
::SaliBode := Alltrim( ::SaliBode )
::CajaDiaria := Alltrim( ::CajaDiaria )
ENDINI
return( Self )
// --------------------------------------------------------------------------------------------
METHOD Save( oDbf ) CLASS MyApp
local oIni
if !empty( ::Usuario )
INI oIni FILE (::cPathLocal + "\wInvent.ini")
oIni:Set( "Usuario", "Usuario", ::Usuario )
oIni:Set( "Usuario", "Nombre", ::Nombre )
oIni := NIL
endif
return( NIL )
// --------------------------------------------------------------------------------------------
Function ViewUsu()
Return( oApp )
// --------------------------------------------------------------------------------------------
static function VerUpdate()
local oIniUpdate, oIniLocal, cVersion, cVersion2, lReturn := .f.
if !file( ViewUsu():cPathUpd + "\Update.exe" ) .or. !file( ViewUsu():cPathUpd + "\Wcta.exe" )
return( lReturn )
endif
INI oIniUpdate FILE ( ViewUsu():cPathUpd + "\update.ini" )
GET cVersion SECTION "Version" ENTRY "numero" OF oIniUpdate DEFAULT "1.0.0"
INI oIniLocal FILE (ViewUsu():cPathLocal + "\wInvent.ini")
GET cVersion2 SECTION "Version" ENTRY "Version" OF oIniLocal DEFAULT "1.0.0"
if PadR( cVersion2,6 ) <> PadR( cVersion,6 )
if Parame->( NetRLock() )
Parame->Version := cVersion
WinExec( ViewUsu():cPathUpd+"\Update.exe "+cVersion )
lReturn := .t.
endif
endif
USE
return( lReturn )
//------------------------------------------------------------------------------------------------
- Code: Select all Expand view
//programa update.exe
//este debe compilarse solo...
#include "ini.ch"
#include "FiveWin.ch"
#Define DRIVELOCAL DiskName() + ":\"+Curdir()
//----------------------------------------------------------------------------
function Update( cValor )
local PATHSERVER, PATHDATOS, lExe, oIni, Usuario
if empty( cValor )
return( .f. )
endif
INI oIni FILE (DRIVELOCAL + "\wInvent.ini")
GET Usuario SECTION "Usuario" ENTRY "Usuario" OF oIni DEFAULT ""
GET PATHSERVER SECTION "Servidor" ENTRY "Update" OF oIni DEFAULT ""
GET PATHDATOS SECTION "Servidor" ENTRY "Name" OF oIni DEFAULT ""
ENDINI
if !file( PATHSERVER + "\wcta.exe" )
MsgInfo( "Falta un archivo imposible actualizar" +CRLF+;
PATHSERVER + "\wcta.exe", "Usuario" )
return( .f. )
endif
if file( DRIVELOCAL + "\wcta.ex_" )
if fErase( DRIVELOCAL + "\wcta.ex_" ) = -1
MsgInfo( "Favor borrar archivo de respaldo "+DRIVELOCAL + "\wcta.ex_", "Usuario" )
return( .f. )
endif
endif
MsgInfo( "Actualización Sistema Win-Facturación" + CRLF + "Versión "+cValor )
if fRename( DRIVELOCAL + "\wcta.exe", DRIVELOCAL + "\wcta.ex_" ) = -1
Msginfo( "Error al actualizar"+CRLF+"Cierre todos las ventanas del sistema"+CRLF+CRLF+ "si persiste este error reinicie la maquina", "usuario" )
return( .f. )
endif
Usuario := Alltrim( Usuario )
lExe := .f.
MsgRun( "Actualizando aplicación..", "Espere..", ;
{ || lExe := CopyFile( PATHSERVER + "\wcta.exe",;
DRIVELOCAL + "\wcta.exe", .f. ) } )
if lExe //sa ha copiado correctamente
oIni := TIni():New( DRIVELOCAL + "\wInvent.Ini" )
oIni:Set( "Version", "Version", cValor )
oIni:Set( "Creado", "Programador", "Patricio Avalos Aguirre" )
oIni:Set( "Creado", "Email", "patricio_avalos_aguirre@hotmail.com" )
oIni:Set( "Creado", "Copyright(c)", "2005" )
MsgInfo( "Actualización se ha realizado con éxito" + CRLF + CRLF +;
"Vuelva a ejecutar el sistema", "Agrotec Ltda." )
fErase( DRIVELOCAL + "\wcta.ex_" )
else
if file( DRIVELOCAL + "\wcta.exe" )
fErase( DRIVELOCAL + "\wcta.exe" )
endif
fRename( DRIVELOCAL + "\wcta.ex_", DRIVELOCAL + "\wcta.exe" ) //volvemos el resplado a su origen
MsgInfo( "Error Al actualizar!!"+ CRLF + CRLF + "EXE Error" + CRLF + CRLF + ;
"Comuniquese con Patricio Avalos Aguirre"+CRLF+"Email:patricio_avalos_aguirre@hotmail.com", "Actualización" )
endif
Return( .t. )
//-----------------------------------------------------------------------------------------------------
//no recuerdo el autor de esta funcion, pero no es mía
static function CopyFile( cORIGEN, cDestino, lBorrar )
local cBuffer, fIfile, fOfile, nNumRead
DEFAULT lBorrar := .F.
#DEFINE BUF_SIZE 1024
cBuffer := SPACE(BUF_SIZE)
fIfile := FOPEN(cORIGEN)
IF FERROR() != 0
MsgStop("Error no se ha podido abrir el fichero "+ CRLF+ CRLF + cORIGEN )
return( .f. )
ENDIF
fOFile := LCreat( cDestino,0 )
IF FERROR() != 0
MsgStop("Error no se ha podido crear el fichero "+CRLF+cDESTINO)
FCLOSE(fIFile)
return( .f. )
ENDIF
nNumRead := FREAD(fIfile,@cBuffer,BUF_SIZE)
DO WHILE nNumRead == BUF_SIZE
FWRITE(fOfile, cBuffer, BUF_SIZE)
nNumRead := FREAD(fIFile,@cBuffer,BUF_SIZE)
ENDDO
FWRITE(fOfile, cBuffer, nNumRead)
FCLOSE(fIFile)
FCLOSE(fOFile)
IF lBorrar
FERASE(cORIGEN)
ENDIF
return( .t. )
//------------------------------------------------------------------------------------------------
Espero que te sirva,
Saludos
Patricio
La Serena, Chile
Posted:
Thu Jul 13, 2006 6:31 pm
by RodolfoRBG
Patricio: Gracias por tus atenciones, tu proceso es muy similar al que estaba desarrollando y me diste buenos tips.
Maestro Flores: El secreto fue la funcion: PostQuitMessage(0) era lo que realmente necesitaba, eres un genio, no se que haces en otros lados con tus experimentos, tu mision en la vida es quedarte con nosotros.
P.D.: Con todo los tips que me dieron esto ya funciono, pero les paso otro, para que funcione correctamente todo esto es necesario que al inicio del exe al que se llama, se coloque un MSGINFO() pues al parecer requiere hacer una pausa para que se termine de cerrar el EXE de donde fue llamado.
'chas gracias
Posted:
Fri Jul 14, 2006 6:39 pm
by Maurilio Viana
RodolfoRBG wrote:Patricio: Gracias por tus atenciones, tu proceso es
(...) se coloque un MSGINFO() pues al parecer requiere hacer una pausa para que se termine de cerrar el EXE de donde fue llamado.
Rodolfo se no quieres nadie visual en inicio del EXE llamado cambia msginfo a SysWait( nSeconds ).
Saludos
Maurilio