 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Jue 21 Feb, 2008 10:54 pm Asunto: Actualizar aplicación |
|
|
Bueno, después de pegarme con el 2007 y dominarlo (que iluso soy), voy a pasaros una aplicación que me ha funcionado medio bien para actualizar automáticamente nuestras aplicaciones.
La cosa empieza desde nuestra aplicación, buscando si hay una actualización pendiente. Yo lo he hecho poniendo el numero de versión por nombre, 1.5.5.5.exe sería MyPrograma.exe versión 1.5.5.5
Os pongo todo el código necesario. Empecemos por MyPrograma.exe y la búsqueda de la actualización en nuestro ftp:
| Código: | TStringList *lista = new TStringList;
AnsiString version;
try{
ftp->Connect();
if(ftp->Connected()){
try{
ftp->List(lista,"*.exe",false);
}
catch(...){
// archivo no encontrado
}
}
ftp->Quit();
}
catch(...){
// no hay conexion
}
// verificar nueva versión
if(lista->Count){
GetVersionInfo(version); // averiguar nuestra version
version=version+".exe";
if(lista->Strings[0]>version){
WinExec("actualizador",SW_SHOW); // se le supone en el mismo directorio
Application->Terminate(); // terminar MyPrograma.exe
}
}
|
La función de "capturar" la versión actual (declararlo en el h):
| Código: | void GetVersionInfo(AnsiString &pVersion)
{
char MyFileName[100]={"MyPrograma.exe"};
struct TFixedFileInfo
{
int Signature;
int StructVersion;
short MinorVersion;
short MajorVersion;
short Build;
short Release;
};
unsigned long Tmp, VersionInfoSize;
VersionInfoSize = GetFileVersionInfoSize( (LPTSTR) MyFileName,&Tmp);
if (VersionInfoSize)
{
TFixedFileInfo *MyFileInfo;
char *MyBuf = new char[VersionInfoSize];
GetFileVersionInfo(MyFileName, 0, VersionInfoSize, MyBuf);
unsigned int ii = sizeof(MyFileInfo);
VerQueryValue(MyBuf, "\\", (void **) &MyFileInfo, &ii);
AnsiString MyString = MyFileInfo->MajorVersion;
AnsiString TmpString = MyString + ".";
MyString = MyFileInfo->MinorVersion;
TmpString += MyString + ".";
MyString = MyFileInfo->Release;
TmpString += MyString + ".";
MyString = MyFileInfo->Build;
TmpString += MyString;
pVersion = TmpString;
VerBs=IntToStr(MyFileInfo->MajorVersion*10000+MyFileInfo->MinorVersion*1000+
MyFileInfo->Release*100+MyFileInfo->Build);
delete [] MyBuf;
} // end if
} // end GetVersionInfo
|
Como podréis ver las funciones para ver si hay actualización es simple. Ahora pasaremos a ejecutar (y ver) el actualizador. Haremos un Form con un TIdFTP, un StaticText y una ProgressBar y este es el código para el cpp. No hay nada modificado en los componentes excepto el nombre del ftp, el user y la password. | Código: | //---------------------------------------------------------------------------
#include <vcl>
#pragma hdrstop
#include "actuali.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "IdExplicitTLSClientServerBase"
#pragma resource "*.dfm"
TForm1 *Form1;
AnsiString nuevo,directorio;
long dlsize;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// directorio de trabajo
directorio=ExtractFilePath(Application->ExeName);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdFTP1Work(TObject *ASender, TWorkMode AWorkMode,
int AWorkCount)
{
ProgressBar1->Position=AWorkCount;
StaticText1->Update();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdFTP1WorkBegin(TObject *ASender, TWorkMode AWorkMode,
int AWorkCountMax)
{
if (AWorkCountMax > 0) ProgressBar1->Max=AWorkCountMax;
else ProgressBar1->Max=dlsize;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdFTP1WorkEnd(TObject *ASender, TWorkMode AWorkMode)
{
AnsiString flocal=directorio+"MyPrograma.exe";
// Actualizado -> parar programa
StaticText1->Caption="Se ha instalado la nueva versión "+nuevo;
Idglobal::Sleep(2000); // unos segundos para leer
WinExec(flocal.c_str(),SW_SHOW); // ejecutar la aplicación
Application->Terminate(); // terminar con el actualizador
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
AnsiString Valor;
TStringList *lista = new TStringList; // lista de archivos
AnsiString flocal=directorio+"MyPrograma.exe"; // nombre de la aplicacion
StaticText1->Update();
try{
IdFTP1->Connect();
if(IdFTP1->Connected()){
try{
// el archivo de actualizacion ya existe segun MyPrograma.exe
IdFTP1->List(lista,"*.exe",false); // buscar archivo
nuevo=lista->Strings[0];
// el nombre es el numero de version 1.5.5.5 (7.3)
Valor=nuevo;
Valor.Delete(nuevo.Length()-3,5); //eliminar .exe
StaticText1->Caption="Descargando actualización del programa Versión "+Valor;
StaticText1->Update(); // necesario
dlsize=IdFTP1->Size(nuevo); // tamaño del archivo
IdFTP1->Get(nuevo,flocal,true); // descargar archivo
// nuevo = nombre del archivo en el ftp
// flocal = fichero local = nombre de MyPrograma.exe
nuevo=Valor; // pasamos el numero de version a global
}
catch(...){
// archivo no encontrado;
}
}
IdFTP1->Quit();
}
catch(...){
// no hay conexxion
}
}
|
Si hay dudas, ya sabéis que hacer. Si hay mejoras, pues mejor aun
En los comentarios están casi todas las respuestas de porque esto funciona.
Saludos, Bosoft.
PD: Angel, lo he terminado antes de lo esperado. |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Vie 22 Feb, 2008 8:15 am Asunto: |
|
|
Una cosa que se podría hacer es en lugar de verificar la versión mediante el sistema de incluir la misma en el nombre es verificar la fecha del fichero con las funciones FileDateToDateTime y FileAge, de forma que si el programa que hay en el servidor es más moderno que el que corre en la máquina, se descarga y listo.
De todas formas, ¡vaya curro que tiene la herramienta! Muy buena. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
bosoft Master

Registrado: 23 Oct 2005Mensajes: 342
|
Publicado: Vie 22 Feb, 2008 6:58 pm Asunto: |
|
|
Hola Angel:
| Angel escribió: | | Una cosa que se podría hacer es en lugar de verificar la versión mediante el sistema de incluir la misma en el nombre es verificar la fecha del fichero con las funciones FileDateToDateTime y FileAge, de forma que si el programa que hay en el servidor es más moderno que el que corre en la máquina, se descarga y listo. |
No estoy de acuerdo con eso de las fechas. La versión la pones tu, pero la fecha puede variar según la maquina, o el server, con lo cual fallaría algunas veces. Visto lo simple que es comprobar la versión y ponerla en tu aplicación no puede dar a error, aunque para gustos colores. Ya se que tu te mueves como pez en el agua con las fechas, pero yo lo vi muy complicado leer la fecha del archivo en el servidor y peor compararlas.
Gracias por el alago, y si ves algun defecto o mejora, no dudes en comentarlo.
Saludos, Bosoft. |
|
| Volver arriba |
|
 |
frios Lt

Registrado: 20 Nov 2005Mensajes: 79Ubicación: España
|
Publicado: Mar 26 Feb, 2008 9:13 am Asunto: |
|
|
Hola,
yo lo tengo parecido, pero mas complicado, pues para facilitar las actualizaciones tengo la aplicación fragmentada en bpl (me resulta mas fácil que con dll).
Para dar mas información del archivo a descargar, tengo un ini con el mismo nombre del archivo, donde guardo el tamaño(es lo que uso para saber si se actualiza, si es diferente hay que actualizar), si está comprimido(para descargar mas rápido),... incluso si es el mismo actualizador, que tambien se tiene que poder actualizar.
Primero descargo los ini, comprueba los tamaños de los diferentes archivos, y si es necesario descarga los archivos y los sustituye.
Un rollo, pero me funciona. |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|