Abandonar la aplicacion y correr otra

Post Reply
User avatar
RodolfoRBG
Posts: 253
Joined: Tue May 16, 2006 4:46 pm
Location: San Luis Potosi, SLP, Mexico
Contact:

Abandonar la aplicacion y correr otra

Post 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
RodolfoRBG
FWH 1307, xHarbour123 BCC582
rodolfoerbg@gmail.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Rodolfo,

Lo más sencillo es usar un fichero BAT que es el que llama a los ejecutables.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
karinha
Posts: 4882
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil

Post 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
João Santos - São Paulo - Brasil
User avatar
RodolfoRBG
Posts: 253
Joined: Tue May 16, 2006 4:46 pm
Location: San Luis Potosi, SLP, Mexico
Contact:

Post 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
RodolfoRBG
FWH 1307, xHarbour123 BCC582
rodolfoerbg@gmail.com
User avatar
wmormar
Posts: 1050
Joined: Fri Oct 07, 2005 10:41 pm
Location: México
Contact:

Post 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
William, Morales
Saludos

méxico.sureste
infosys
Posts: 57
Joined: Tue Jan 31, 2006 1:32 pm

Post 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.
User avatar
RodolfoRBG
Posts: 253
Joined: Tue May 16, 2006 4:46 pm
Location: San Luis Potosi, SLP, Mexico
Contact:

Post 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.
RodolfoRBG
FWH 1307, xHarbour123 BCC582
rodolfoerbg@gmail.com
R.F.
Posts: 840
Joined: Thu Oct 13, 2005 7:05 pm

Post 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")
Saludos
R.F.
User avatar
Patricio Avalos Aguirre
Posts: 1028
Joined: Fri Oct 07, 2005 1:56 pm
Location: La Serena, Chile
Contact:

Post 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

_____________________________________________________________ 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. )
//------------------------------------------------------------------------------------------------
Espero que te sirva,

Saludos
Patricio

La Serena, Chile
User avatar
RodolfoRBG
Posts: 253
Joined: Tue May 16, 2006 4:46 pm
Location: San Luis Potosi, SLP, Mexico
Contact:

Post 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
RodolfoRBG
FWH 1307, xHarbour123 BCC582
rodolfoerbg@gmail.com
User avatar
Maurilio Viana
Posts: 252
Joined: Tue Oct 25, 2005 2:48 pm
Location: Garça/Garza/Heron City - Brazil
Contact:

Post 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
Post Reply