FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Abandonar la aplicacion y correr otra
Posts: 257
Joined: Tue May 16, 2006 04:46 PM
Abandonar la aplicacion y correr otra
Posted: Tue Jul 11, 2006 07:04 PM

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
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Abandonar la aplicacion y correr otra
Posted: Tue Jul 11, 2006 08:55 PM

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
Posts: 8515
Joined: Tue Dec 20, 2005 07:36 PM
Abandonar la aplicacion y correr otra
Posted: Tue Jul 11, 2006 08:58 PM

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 - Phone: +55(11)95150-7341
Posts: 257
Joined: Tue May 16, 2006 04:46 PM
Abandonar la aplicacion y correr otra
Posted: Wed Jul 12, 2006 01:13 AM

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
Posts: 1076
Joined: Fri Oct 07, 2005 10:41 PM
Abandonar la aplicacion y correr otra
Posted: Wed Jul 12, 2006 02:55 AM
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
Posts: 59
Joined: Tue Jan 31, 2006 01:32 PM
Abandonar la aplicacion y correr otra
Posted: Wed Jul 12, 2006 07:39 PM

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.

Posts: 257
Joined: Tue May 16, 2006 04:46 PM
Abandonar la aplicacion y correr otra
Posted: Wed Jul 12, 2006 07:57 PM

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
Posts: 840
Joined: Thu Oct 13, 2005 07:05 PM
Abandonar la aplicacion y correr otra
Posted: Thu Jul 13, 2006 12:24 AM

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.
Posts: 1074
Joined: Fri Oct 07, 2005 01:56 PM
Abandonar la aplicacion y correr otra
Posted: Thu Jul 13, 2006 02:07 PM
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

_____________________________________________________________ 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


#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 )
//------------------------------------------------------------------------------------------------



//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
Saludos
Patricio

__________________________________________________________________
Version: Harbour 3.2.0dev (r1307082134),Compiler: Borland C++ 5.8.2 (32-bit)
PCode version: 0.3, FWH 13.2
http://www.sialm.cl
Posts: 257
Joined: Tue May 16, 2006 04:46 PM
Abandonar la aplicacion y correr otra
Posted: Thu Jul 13, 2006 06:31 PM

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
Posts: 252
Joined: Tue Oct 25, 2005 02:48 PM
Abandonar la aplicacion y correr otra
Posted: Fri Jul 14, 2006 06:39 PM
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

Continue the discussion