Abandonar la aplicacion y correr otra
- RodolfoRBG
- Posts: 253
- Joined: Tue May 16, 2006 4:46 pm
- Location: San Luis Potosi, SLP, Mexico
- Contact:
Abandonar la aplicacion y correr otra
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
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
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
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
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
João Santos - São Paulo - Brasil
- RodolfoRBG
- Posts: 253
- Joined: Tue May 16, 2006 4:46 pm
- Location: San Luis Potosi, SLP, Mexico
- Contact:
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
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 probarRodolfoRBG 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
SHELLEXECUTE()
oWnd:END()
por ahi va la idea
William, Morales
Saludos
méxico.sureste
Saludos
méxico.sureste
- RodolfoRBG
- Posts: 253
- Joined: Tue May 16, 2006 4:46 pm
- Location: San Luis Potosi, SLP, Mexico
- Contact:
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")
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")
Saludos
R.F.
R.F.
- Patricio Avalos Aguirre
- Posts: 1028
- Joined: Fri Oct 07, 2005 1:56 pm
- Location: La Serena, Chile
- Contact:
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
Espero que te sirva,
Saludos
Patricio
La Serena, Chile
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
_____________________________________________________________ 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
#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
//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. )
//------------------------------------------------------------------------------------------------
Saludos
Patricio
La Serena, Chile
- RodolfoRBG
- Posts: 253
- Joined: Tue May 16, 2006 4:46 pm
- Location: San Luis Potosi, SLP, Mexico
- Contact:
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
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
- Maurilio Viana
- Posts: 252
- Joined: Tue Oct 25, 2005 2:48 pm
- Location: Garça/Garza/Heron City - Brazil
- Contact:
Rodolfo se no quieres nadie visual en inicio del EXE llamado cambia msginfo a SysWait( nSeconds ).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.
Saludos
Maurilio