Page 1 of 1

Funcion para actualizacion a traves de internet

Posted: Tue Aug 22, 2006 2:36 pm
by George
Esto lo desarolle para las actualizaciones automaticas a taves de internet.
Si algun compañero del foro le quiere hacer alguna mejora bienvenido.

Code: Select all

FUNCTION Main()
// En este ejemplo el nombre de nuestro programa es 'MyProgram.exe'
// el nombre de la nueva version a bajar del server es '_MyProgram.exe'

  //Añadir al inicio del programa

  // Nombre de la aplicacion que esta corriendo, incluyendo la ruta
  cPathAppliName := 	alltrim(hb_argv( 0 ))
  nLen := len(cPathAppliName)
  nAtNum := atnum( "\", cPathAppliName)
  nPos := nLen - nAtNum

  // Nombre de la aplicacion que esta corriendo unicamente
  // Puede ser 'MyProgram.exe' o "_MyProgram.exe"
  cAppliName := right(cPathAppliName, nPos)

  // Nombre original de mi programa
  cOrigAppli := alltrim(cAppliDir) + "\MyProgram.exe"

  // Ck si esta corriendo el update recien bajado
	IF upper((cPathAppliName)) <> upper((cOrigAppli))
		 // Esta corriendo la nueva version

		 // Borrar la version original 'MyProgram.exe'
		 ferase(cOrigAppli) <> 0
		 syswait(1)

		 // Renombrar la nueva version con el nombre de mi programa original
		 RENAME  "_MyProgram.exe" TO "MyProgram.exe"
	ENDIF

	/*

	Su codigo de su programa

	*/


RETURN (.T.)


FUNCTION CkUpdate()
	// Esta es la funcion que se debe ejecutar para
	//verificar si existe una nueva version del programa

	dbselectarea("PATHFILE")                     // Archivo donde estan los parametros del server
	cAlias := alias()
	GO 1

	cServFtp := alltrim((cAlias)->SERVER) // Direccion del server
	cUserFTp := alltrim((cAlias)->USER)   // User  Name
	cPassFTp := alltrim((cAlias)->PASSW)   // Password
	cServPath := alltrim((cAlias)->SERPATH) // Ruta del server donde esta '_MyProgram.exe'
	cVersion2 := (cAlias)->VERSION          // Version actual de 'MyProgram.exe'

	Dbcloseall()

	// Ir al server a bajar la informacion de la nueva version, si existe
	IF !GetUpdateFromServer(cServFtp, cUserFTp, cPassFTp, cServPath, cVersion2 )
		// No existe nueva version o la conexion al server fallo
		RETURN .F.
	ENDIF

	// Se bajo del server la nueva version '_MyProgram.exe'
	cFileExe := (cAppliDir) + "\_MyProgram.exe"

	OpenFiles() // Funcion para abrir los archivos (tablas) de la base de datos

	// Correr la nueva version bajada del server ''_MyProgram.exe'
	WinExec("_MyProgram.exe")

	// 'Matar' el programa actual 'MyProgram.exe'
	PostQuitMessage(0)
	__Quit()

RETURN (.T.)


Function GetUpdateFromServer( cServFtp, cUserFTp, cPassFTp, cServPath, cVersion2 )

	Local oInternet, oFtp, oMeter, oText
	Local cTitle := "Connecting to SDN Server", lExistAlt := .F.
	LOCAL hInternet, hConnect, cAlias, cAlias1, cNewTitle, lGetFileAll := .F.

	PRIVATE oSay

	// Dialogo con un mensaje indicando la conexion al server
	DEFINE DIALOG oDlg RESOURCE "DIALOG_13";
		TITLE cTitle

	REDEFINE SAY oSay ID 55 of oDlg

	ACTIVATE DIALOG oDlg NOWAIT

	oSay:SetText ("Checking for update....")

	hLib = LOADLIBRARY( "wininet.dll" )

	hInternet = INETOPEN( "Anystring", INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0 )

	hConnect = INETCONNECT( hInternet, cServFtp, INTERNET_INVALID_PORT_NUMBER,;
		cUserFTp, cPassFTp, INTERNET_SERVICE_FTP, 0, 0 )

	IF hConnect = 0
		MsgAlert("Connection to server failed!" + chr(13)+;
			"Please check your internet connection and try later.")
		oDlg:end()
		OpenFiles()  // Funcion para abrir los archivos (tablas) de la base de datos
		RETURN .F.
	ENDIF


	// P_VERS.DBF es un archivo con un campo con el No. de la version
	cDownUPD := cAppliDir + "\P_VERS.DBF"
	cLastUPD := cServPath + "/P_VERS.DBF"

	lGetLastUPD := FTPGETFILE( hConnect, cLastUPD, cDownUPD, 0, FILE_ATTRIBUTE_ARCHIVE, 0, 0 )

	IF !lGetLastUPD
		MsgAlert("P_VERS Downloaded failed!" + chr(13) +;
			"Please check your internet connection!")
		INETCLOSEHANDLE( hConnect )
		INETCLOSEHANDLE( hInternet )
		FREELIBRARY( hLib )
		OpenFiles()
		oDlg:End()
		RETURN .F.
	ENDIF

	OpenFiles()

	dbselectarea("P_VERS")
	cAlias := alias()
	GO 1
	cVersion1 := (cAlias)->VERSION

	dbcloseall()

	// Se compara el No. de la version del programa corriendo
	// con el No. de la version del programa en el server
	IF alltrim(cVersion1) == alltrim(cVersion2)

		// Si es el mismo numero no se baja la version del programa que esta en el Server
		Msginfo(" You already have the most recent version.")
		INETCLOSEHANDLE( hConnect )
		INETCLOSEHANDLE( hInternet )
		FREELIBRARY( hLib )
		OpenFiles()
		oDlg:End()
		RETURN .F.
	ENDIF


	// Si son diferentes se baja la version del programa que esta en el Server
	cDataSDN := cServPath + "/_MyProgram.exe"
	cPathDir := cAppliDir + "\_MyProgram.exe"

	oDlg:End()

	MsgRun( "Downloading Update Files Please Wait...", "My Program",;
		{ || lGetFileAll := FTPGETFILE( hConnect, cDataSDN, cPathDir, 0, FILE_ATTRIBUTE_ARCHIVE, 0, 0 ) } )

	IF !lGetFileAll
		MsgAlert("File Downloaded failed!" + chr(13) +;
			"Please check your internet connection!")
		INETCLOSEHANDLE( hConnect )
		INETCLOSEHANDLE( hInternet )
		FREELIBRARY( hLib )
		OpenFiles()
		RETURN .F.
	ENDIF

	INETCLOSEHANDLE( hConnect )
	INETCLOSEHANDLE( hInternet )
	FREELIBRARY( hLib )

	oDlg:end()
RETURN .T.

George

Re: Funcion para actualizacion a traves de internet

Posted: Tue Aug 22, 2006 4:34 pm
by Maurilio Viana
Muchas gracias, George!!!

Saludos de Brasil
Maurilio

Posted: Tue Aug 22, 2006 5:17 pm
by George
A tu orden Maurilio

Aqui estan unos DEFINES que necesita para el manejo de transferencia de archivos a traves de internet. Hice varias pruebas y estas funciones me trabajan perfectamente en FWH 2.5 + xHarbour builder FEB 2005.

Elimine los dbcloseall() y los openfiles(). Ahora solo cierro el area de P_VERS que es la que se sobreescribe con el nuevo numero de la version.


George

Code: Select all

//
// File attributes
//

#define FILE_ATTRIBUTE_READONLY  1
#define FILE_ATTRIBUTE_HIDDEN    2
#define FILE_ATTRIBUTE_SYSTEM    4
#define FILE_ATTRIBUTE_DIRECTORY 16
#define FILE_ATTRIBUTE_ARCHIVE   32
#define FILE_ATTRIBUTE_NORMAL    128
#define FILE_ATTRIBUTE_TEMPORARY 256


//
// access types for InternetOpen()
//

#define INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
#define INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
#define INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
#define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS


//
// manifests
//

#define INTERNET_INVALID_PORT_NUMBER    0           // use the protocol-specific default

#define INTERNET_DEFAULT_FTP_PORT       21      // default for FTP servers
#define INTERNET_DEFAULT_GOPHER_PORT    70      //    "     " gopher "
#define INTERNET_DEFAULT_HTTP_PORT      80      //    "     " HTTP   "
#define INTERNET_DEFAULT_HTTPS_PORT     443     //    "     " HTTPS  "
#define INTERNET_DEFAULT_SOCKS_PORT     1080    // default for SOCKS firewall servers.


//
// service types for InternetConnect()
//

#define INTERNET_SERVICE_FTP     1
#define INTERNET_SERVICE_GOPHER  2
#define INTERNET_SERVICE_HTTP    3

//
// flags for FTP
//

#define INTERNET_FLAG_TRANSFER_ASCII  1
#define INTERNET_FLAG_TRANSFER_BINARY 2



Posted: Tue Aug 22, 2006 6:10 pm
by Frafive
Muy bueno George

Y para subir un archivo a un sitio ftp, como se haria ?


Un saludo y gracias desde ya

Posted: Tue Aug 22, 2006 7:55 pm
by George
Aqui tienes la funcion para el upload y tambien los wrapper de las funciones que necesitas para manejar las transferencias
Todo esto combinado con los codigo anteriores te permite la transferencia de archivos y la actualizaciones de tu aplicacion * EN TIEMPO REAL * y sin tener abortar la aplicacion ni usar batch, a traves de internet.

Quizas unos de los guru del foro se anima y basado en estas funciones hace una clase que podamos integrar facilmente en nuestra aplicaciones.

George

Code: Select all


FUNCTION SendToFtp()

    LOCAL hInternet, hConnect

    hLib = LOADLIBRARY( "wininet.dll" )

    hInternet = INETOPEN( "Anystring", INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0 )

    hConnect = INETCONNECT( hInternet, "ftp address", INTERNET_INVALID_PORT_NUMBER,;
    	 "userid", "password", INTERNET_SERVICE_FTP, 0, 0 )

    ? FTPPUTFILE( hConnect, "local file name", "remote file name", 0, 0 )

    INETCLOSEHANDLE( hConnect )

    INETCLOSEHANDLE( hInternet )

    FREELIBRARY( hLib )

    RETURN NIL


DLL32 FUNCTION INETOPEN( cAgent AS LPSTR, nAccessType AS DWORD, cProxyName AS LPSTR, cProxyBypass AS LPSTR, nFlags AS DWORD ) AS LONG;
      PASCAL FROM "InternetOpenA" LIB hLib

DLL32 FUNCTION INETCLOSEHANDLE( hInternet AS LONG ) AS BOOL;
      PASCAL FROM "InternetCloseHandle" LIB hLib

DLL32 FUNCTION INETCONNECT( hInternet AS LONG, cServerName AS LPSTR,;
nServerPort AS LONG, cUserName AS LPSTR, cPassword AS LPSTR, nService AS DWORD, nFlags AS DWORD, @nContext AS PTR ) AS LONG;
      PASCAL FROM "InternetConnectA" LIB hLib

DLL32 FUNCTION FTPGETFILE( hConnect AS LONG, cRemoteFile AS LPSTR, cNewFile AS LPSTR,;
	 nFailIfExists AS LONG, nFlagsAndAttribs AS DWORD, nFlags AS DWORD, @nContext AS PTR ) AS BOOL;
      PASCAL FROM "FtpGetFileA" LIB hLib

DLL32 FUNCTION FTPPUTFILE( hConnect AS LONG, cLocalFile AS LPSTR, cNewRemoteFile AS LPSTR,;
	 nFlags AS DWORD, @nContext AS PTR ) AS BOOL;
      PASCAL FROM "FtpPutFileA" LIB hLib