01732b3762
Files correlati : ba1.exe Ricompilazione Demo : [ ] Commento : Errore 1372 Corretto aggiornamento cartella setup su client. git-svn-id: svn://10.65.10.50/trunk@19048 c028cbd2-c16b-5b4b-a496-9718f37d4682
1922 lines
56 KiB
C++
Executable File
1922 lines
56 KiB
C++
Executable File
#include <agasys.h>
|
||
#include <applicat.h>
|
||
#include <execp.h>
|
||
#include <isamrpc.h>
|
||
#include <modaut.h>
|
||
#include <prefix.h>
|
||
#include <progind.h>
|
||
#include <sheet.h>
|
||
#include <statbar.h>
|
||
#include <urldefid.h>
|
||
#include <utility.h>
|
||
|
||
#include "ba1.h"
|
||
#include "ba1500.h"
|
||
#include "ba1600.h"
|
||
#include "ba1700a.h"
|
||
|
||
// definizioni delle colonne dello sheet
|
||
#define C_MODULE 1
|
||
#define C_CODE 2
|
||
#define C_RELEASE 3
|
||
#define C_PATCH 4
|
||
#define C_DATAREL 5
|
||
#define C_CURRRELEASE 6
|
||
#define C_CURRPATCH 7
|
||
#define C_CURRDATAREL 8
|
||
#define C_ISPATCH 9
|
||
#define C_BASEPATCH 10
|
||
|
||
|
||
///////////////////////////////////////////////////////
|
||
// Metodi di utility
|
||
///////////////////////////////////////////////////////
|
||
HIDDEN const TString& http_default_path()
|
||
{
|
||
//nuovo modo di gettare il producer da oem.ini
|
||
TConfig oemini(CONFIG_OEM, "MAIN");
|
||
const int oem = oemini.get_int("OEM", NULL, -1, -1);
|
||
TString& tmp = get_tmp_string();
|
||
if (oem >= 0)
|
||
{
|
||
TString8 para; para << "OEM_" << oem;
|
||
tmp = oemini.get("Web", para);
|
||
}
|
||
if (tmp.blank())
|
||
tmp = "www.aga.it/release100/";
|
||
|
||
return tmp;
|
||
}
|
||
|
||
HIDDEN int compare_version(const char* v1, int p1, const char* v2, int p2)
|
||
{
|
||
TString16 ver1(v1), ver2(v2);
|
||
|
||
ver1.trim();
|
||
ver1.ltrim(ver1.len() == 4 ? 2 : 4);
|
||
ver2.trim();
|
||
ver2.ltrim(ver2.len() == 4 ? 2 : 4);
|
||
|
||
int res = ver1.compare(ver2, -1, TRUE);
|
||
|
||
if (res == 0)
|
||
|
||
res = p1 - p2;
|
||
|
||
return res;
|
||
}
|
||
|
||
HIDDEN word version2year(const char* v)
|
||
{
|
||
TString16 ver(v);
|
||
if (ver.len() == 4)
|
||
ver.insert((v[0] == '9') ? "19" : "20", 0);
|
||
ver.cut(4);
|
||
return atoi(ver);
|
||
}
|
||
|
||
static int compare_modules(const TObject** o1, const TObject** o2)
|
||
{
|
||
TToken_string& ts1 = *(TToken_string*)(*o1);
|
||
TToken_string& ts2 = *(TToken_string*)(*o2);
|
||
|
||
int res = 0;
|
||
for (int i = 2; i < 5 && res == 0; i++)
|
||
{
|
||
TString16 s1 = ts1.get(i);
|
||
const char* s2 = ts2.get(i);
|
||
res = s1.compare(s2);
|
||
}
|
||
return res;
|
||
}
|
||
|
||
bool is_internet_path(const TString& addr)
|
||
{
|
||
if (addr.starts_with("www.", true) || addr.starts_with("http:", true))
|
||
return true;
|
||
|
||
int a1, a2, a3, a4;
|
||
if (sscanf(addr, "%d.%d.%d.%d", &a1, &a2, &a3, &a4) == 4)
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Maschera principale
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TInstaller_mask : public TArray_sheet
|
||
{
|
||
static TInstaller_mask* _curr_mask;
|
||
int _station_type; //intero che definisce il tipo di installazione (1=std,2=server,3=client)
|
||
bool _installed; // Flag per verificare se almeno un modulo e' stato installato
|
||
bool _setup_run; //Flag che indica se e' stato lanciato il programma setup.exe
|
||
|
||
enum { NONE=0, NEW_MENU=1,
|
||
NEW_MENUPRG=2, NEW_INSTALLER=4, NEW_DLL=8, NEW_SYS=14,
|
||
NEW_TRR=16 };
|
||
int _reboot_program;
|
||
|
||
protected: // TSheet
|
||
virtual bool on_key(KEY key);
|
||
static bool tutti_handler(TMask_field& f, KEY k);
|
||
int get_module_number(const TString& module) const;
|
||
bool should_precheck_module(int modnumber) const;
|
||
bool is_zip_file(const TFilename& n) const;
|
||
|
||
bool copy_file(const TFilename& src, const TFilename& dst) const;
|
||
bool copy_tree(const char* src_study, const char* dst_study) const;
|
||
int test_station_type() const;
|
||
|
||
protected:
|
||
static bool path_handler(TMask_field& fld, KEY key);
|
||
static bool web_handler(TMask_field& fld, KEY key);
|
||
static bool sheet_notify(TSheet_field& s, int r, KEY k);
|
||
static bool install_handler(TMask_field& fld, KEY key);
|
||
static bool update_handler(TMask_field& f, KEY k);
|
||
|
||
bool add_module(TConfig& ini, const TString& module, bool patch, int pos = -1);
|
||
bool add_header(TConfig& ini, const TString& module);
|
||
int precheck_modules(bool only_newer = true);
|
||
void update_version();
|
||
void update_disk_and_web_path();
|
||
void kill_files();
|
||
|
||
int needs_reboot(const TFilename& file) const;
|
||
bool move_file(const TFilename& src, const TFilename& dst) const;
|
||
bool move_module(const TString& module, TInstall_ini& ini, bool update) const;
|
||
|
||
bool can_install(const char* module, TInstall_ini& ini);
|
||
void install_selection();
|
||
bool install_patches(const TString& module, const TString& lastrelease, int lastpatch , bool onlynew = true);
|
||
KEY askdisk(TString& path, TFilename& cmdline, int d, int dischi, const char* modulo);
|
||
|
||
bool do_process(TToken_string& commands) const;
|
||
bool pre_process(TInstall_ini& ini, const char* module) const;
|
||
bool post_process(TInstall_ini& ini, const char* module) const;
|
||
bool get_patches_path(TFilename& path) const;
|
||
void parse_internet_path(TString& http_server, TFilename& http_path) const;
|
||
bool is_program_dir(const TFilename& path);
|
||
bool is_visible_patch(TConfig& ini) const;
|
||
|
||
public:
|
||
bool installed() const { return _installed;}
|
||
bool setup_run() const { return _setup_run; }
|
||
int station_type() const {return _station_type;}
|
||
bool autoload();
|
||
bool install(const TString& module, int patch);
|
||
|
||
void backup() const;
|
||
|
||
bool run_conversion() const
|
||
{ return installed() && (_reboot_program & NEW_TRR) != 0; }
|
||
|
||
TInstaller_mask();
|
||
virtual ~TInstaller_mask();
|
||
};
|
||
|
||
TInstaller_mask* TInstaller_mask::_curr_mask = NULL;
|
||
|
||
|
||
bool TInstaller_mask::is_visible_patch(TConfig& ini) const
|
||
{
|
||
bool yes = true;
|
||
|
||
const TString& module = ini.get_paragraph();
|
||
CHECKS(module.len() == 2, "Invalid module ", (const char*)module);
|
||
const int mod = dongle().module_name2code(module);
|
||
if (mod > BAAUT && mod < ENDAUT)
|
||
{
|
||
TAuto_token_string oem = ini.get("OEM");
|
||
if (oem.blank())
|
||
{
|
||
// Pezza temporanea: assegno OEM noti
|
||
switch (mod)
|
||
{
|
||
case LVAUT: oem = "2,4"; break;
|
||
case PEAUT: oem = "3"; break;
|
||
case COAUT: oem = "5"; break;
|
||
default: break;
|
||
};
|
||
}
|
||
|
||
if (oem.full())
|
||
yes = oem.get_pos(dongle().oem()) >= 0;
|
||
else
|
||
{
|
||
// Pezza temporanea: Ee significava AGA only
|
||
const bool ee = ini.get_bool("Ee");
|
||
if (ee && dongle().oem() != 0)
|
||
yes = false;
|
||
}
|
||
}
|
||
return yes;
|
||
}
|
||
|
||
// Copia nello sheet i dati di un modulo prendendoli da un .ini
|
||
bool TInstaller_mask::add_module(TConfig& ini, const TString& module, bool patch, int pos)
|
||
{
|
||
ini.write_protect();
|
||
if (!ini.set_paragraph(module))
|
||
return false;
|
||
|
||
// Nasconde i moduli riservati da occhi indiscreti
|
||
if (!is_visible_patch(ini))
|
||
return false;
|
||
|
||
const int numpatch = ini.get_int("Patch");
|
||
TString4 strpatch;
|
||
if (numpatch > 0)
|
||
strpatch.format("%04d", numpatch);
|
||
|
||
TToken_string row;
|
||
row = " "; // Not selected
|
||
row.add(ini.get("Descrizione"));
|
||
row.add(module);
|
||
row.add(ini.get("Versione"));
|
||
row.add(strpatch);
|
||
row.add(ini.get("Data"));
|
||
row.add(patch ? "X" : " ", C_ISPATCH);
|
||
if (pos < 0)
|
||
add(row);
|
||
else
|
||
insert(row,pos);
|
||
|
||
return true;
|
||
}
|
||
|
||
// Copia nello sheet l'intestazione di un modulo prendendola da un .ini
|
||
bool TInstaller_mask::add_header(TConfig& ini, const TString& module)
|
||
{
|
||
ini.write_protect();
|
||
bool ok = ini.set_paragraph(module);
|
||
if (ok)
|
||
{
|
||
TToken_string row;
|
||
row = " "; // Not selected
|
||
row.add(ini.get("Descrizione"));
|
||
row.add(ini.get(" "));
|
||
enable_row(add(row),false);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TInstaller_mask::should_precheck_module(int modnumber) const
|
||
{
|
||
bool ok = modnumber == 0;
|
||
|
||
if (!ok)
|
||
{
|
||
const TDongle& d = dongle();
|
||
if (station_type() == 2)
|
||
{
|
||
//se sei un server hai tutti i moduli da installare
|
||
ok = d.shown(modnumber);
|
||
}
|
||
else
|
||
{
|
||
//senno' sei sfigato e ti installa solo i moduli sulla chiave
|
||
ok = d.active(modnumber);
|
||
if (!ok) // Se non hai un modulo ... potresti avere un suo modulo sottinteso
|
||
{
|
||
switch (modnumber)
|
||
{
|
||
case CAAUT: ok = d.active(CMAUT); break; // Se non hai l'analitica ritenta con le commesse
|
||
case TPAUT: ok = d.active(DCAUT); break; // Se non hai Pack ritenta con il CONAI
|
||
default: break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
//che tipo di installazione e'?
|
||
int TInstaller_mask::test_station_type() const
|
||
{
|
||
TConfig ini(CONFIG_INSTALL, "Main");
|
||
int type = ini.get_int("Type");
|
||
//se type non e' definito nei valori giusti (1=standard,2=server,3=client)
|
||
if (type < 1 || type > 3)
|
||
{
|
||
const bool testdb = ini.get_bool("TestDatabase");
|
||
const bool testprg = ini.get_bool("TestPrograms");
|
||
if (testdb)
|
||
{
|
||
if (dongle().hardware() == _dongle_network) //se usa un server di chiavi->server
|
||
type = 2;
|
||
else
|
||
type = 1;
|
||
}
|
||
else
|
||
type = 3;
|
||
|
||
ini.set("Type", type); //cosi' lo definisce se non c'e'
|
||
}
|
||
return type;
|
||
}
|
||
|
||
int TInstaller_mask::precheck_modules(bool only_newer)
|
||
{
|
||
TString16 release,currrelease;
|
||
TString4 cod_module;
|
||
int patchlevel,modnumber,currpatch;
|
||
|
||
bool check_enabled = true;
|
||
_setup_run = false; //inizializzazione del flag di controllo di lancio di setup.exe
|
||
|
||
TString_array& a = rows_array();
|
||
FOR_EACH_ARRAY_ROW(a, r, row)
|
||
{
|
||
TToken_string& rigar = *row;
|
||
cod_module = rigar.get(C_CODE);
|
||
release = rigar.get(C_RELEASE);
|
||
patchlevel = rigar.get_int(C_PATCH);
|
||
currrelease = rigar.get(C_CURRRELEASE);
|
||
currpatch = rigar.get_int(C_CURRPATCH);
|
||
modnumber = get_module_number(cod_module);
|
||
if (modnumber >= 0 && should_precheck_module(modnumber) &&
|
||
release.full() &&
|
||
((release > currrelease) ||
|
||
(release == currrelease && (only_newer ? patchlevel > currpatch : patchlevel >= currpatch) ))
|
||
)
|
||
{
|
||
// spunta il modulo o la patch se ho installata la stessa versione
|
||
bool chk = rigar.get_char(C_ISPATCH) != 'X' || release == currrelease;
|
||
|
||
// non spunta automaticamente il modulo server su installazioni che non siano server
|
||
if (chk && cod_module == "sr" && test_station_type() != 2)
|
||
chk = false;
|
||
|
||
if (check_enabled)
|
||
check(r, chk);
|
||
|
||
if (chk && only_newer && cod_module == "sy") //se viene checkato il modulo sy (sistema) deve togliere..
|
||
{ //..la possibilita' di installare altri moduli..
|
||
for (int i = 0; i < a.items(); i++)
|
||
disable_row(i); //disabilita tutte le righe dello sheet
|
||
disable(DLG_USER);
|
||
check_enabled = false; //..ed uscire
|
||
}
|
||
} //if(modnumber>=0...
|
||
} //FOR_EACH_ARRAY_ROW...
|
||
force_update(); // Indispensabile per vedere le righe aggiornate sullo sheet
|
||
return items();
|
||
}
|
||
|
||
|
||
int TInstaller_mask::get_module_number(const TString& module) const
|
||
{
|
||
int aut = -1;
|
||
bool ok = false;
|
||
if (module.full())
|
||
{
|
||
if (module == "ba" || module == "sy") //moduli base e sistema: deve ritornare 0;
|
||
return 0;
|
||
|
||
aut = dongle().module_name2code(module);
|
||
ok = aut < ENDAUT;
|
||
}
|
||
return ok ? aut : -1;
|
||
}
|
||
|
||
void TInstaller_mask::update_version()
|
||
{
|
||
TInstall_ini ini;
|
||
|
||
TString_array& a = rows_array();
|
||
FOR_EACH_ARRAY_ROW_BACK(a, m, row)
|
||
{
|
||
if (*row->get(C_CODE) != ' ')
|
||
{
|
||
const TString4 module = row->get(C_CODE);
|
||
ini.set_paragraph(module);
|
||
|
||
const TString16 newver = row->get(C_RELEASE);
|
||
const TString16 oldver = ini.get("Versione");
|
||
const int numpatch = ini.get_int("Patch");
|
||
TString4 strpatch;
|
||
if (numpatch > 0)
|
||
strpatch.format("%04d", numpatch);
|
||
row->add(oldver, C_CURRRELEASE);
|
||
row->add(strpatch, C_CURRPATCH);
|
||
row->add(ini.get("Data"), C_CURRDATAREL);
|
||
}
|
||
}
|
||
force_update();
|
||
}
|
||
|
||
// Cerca nel percorso specificato sulla maschera tutti i possibili files .ini
|
||
// utilizzabili per un'installazione e li inserisce nello spreadsheet
|
||
bool TInstaller_mask::autoload()
|
||
{
|
||
TString_array& mask_rows = rows_array();
|
||
|
||
TString http_server;
|
||
TFilename http_path, path, ininame;
|
||
|
||
//controla se si e' scelto un path di installazione internet o da disco
|
||
const bool internet = get_patches_path(path);
|
||
//se e' un aggiornamento via internet...
|
||
if (internet)
|
||
{
|
||
parse_internet_path(http_server, http_path); //controlla il path internet scritto nel campo sulla maschera
|
||
|
||
//se si ritrova dei vecchi file nella directory temporanea, la pulisce per evitare casini
|
||
ininame = path; ininame.add("*.*");
|
||
TString_array list;
|
||
::list_files(ininame, list);
|
||
FOR_EACH_ARRAY_ROW(list, i, row)
|
||
xvt_fsys_remove_file(*row);
|
||
|
||
ininame = path;
|
||
ininame.add(TInstall_ini::default_name());
|
||
if (!ininame.exist())
|
||
{
|
||
TFilename remote_ini = http_path;
|
||
remote_ini << TInstall_ini::default_name();
|
||
{
|
||
TTimerind contacting(30*1000, TR("Connessione al server HTTP..."), false, false);
|
||
http_get(http_server, remote_ini, ininame);
|
||
}
|
||
}
|
||
} //if(internet...
|
||
|
||
if (path.exist())
|
||
{
|
||
ininame = path;
|
||
ininame.add(TInstall_ini::default_name());
|
||
}
|
||
else
|
||
return error_box(TR("Specificare un percorso valido"));
|
||
|
||
TWait_cursor hourglass;
|
||
destroy();
|
||
force_update();
|
||
|
||
TString_array modules;
|
||
|
||
//cerca sull'install.ini di origine se lo trova (ininame e' il path dell'install.ini remoto)
|
||
if (ininame.exist())
|
||
{
|
||
// Presente il file ini generale "install.ini" (moduli;immagine cd)
|
||
TInstall_ini ini(ininame);
|
||
ini.list_paragraphs(modules); //riempie modules con la lista dei paragrafi sul .ini ***
|
||
|
||
FOR_EACH_ARRAY_ROW(modules, i, row)
|
||
{
|
||
const TString& module = *row;
|
||
if (module[0] == '_' || module.len() == 2)
|
||
{
|
||
if (module[0] == '_')
|
||
add_header(ini, module);
|
||
else
|
||
{
|
||
TFilename mod_ini = ininame.path();
|
||
mod_ini.add(module);
|
||
mod_ini << "inst.ini";
|
||
//controlla se esiste il pacco zippato del modulo attraverso l'esistenza del file..
|
||
//..XXinst.ini
|
||
if (mod_ini.exist())
|
||
{
|
||
TInstall_ini moduleini(mod_ini);
|
||
add_module(moduleini, module, false);
|
||
}
|
||
else
|
||
add_module(ini, module, false);
|
||
}
|
||
} //if(module[0]...
|
||
} //FOR_EACH_ARRAY_ROW(...
|
||
}
|
||
else
|
||
{
|
||
// Presenti i singoli file .ini dei moduli (pacchi ma non patches!)
|
||
ininame = path;
|
||
ininame.add("??inst.ini");
|
||
list_files(ininame, modules); //ritorna la lista dei files presenti nel .ini della patch ***
|
||
FOR_EACH_ARRAY_ROW(modules, m, row)
|
||
{
|
||
TString& ininame = *row;
|
||
ininame.lower();
|
||
const int pos = ininame.find("inst.ini");
|
||
CHECKS(pos >= 2, "Invalid installation configuration: ", (const char*)ininame);
|
||
const TString4 module = ininame.mid(pos-2, 2);
|
||
TConfig ini(ininame, module);
|
||
add_module(ini, module, false);
|
||
}
|
||
}
|
||
|
||
modules.destroy();
|
||
|
||
if (internet) //internet patches
|
||
{
|
||
http_dir(http_server, http_path, modules);
|
||
for (int i = modules.last(); i >= 0; i--)
|
||
{
|
||
TString& str = modules.row(i);
|
||
if (str.match("??????A.INI", true))
|
||
{
|
||
TFilename remote = http_path;
|
||
remote << str;
|
||
|
||
ininame = path;
|
||
ininame.add(str);
|
||
|
||
if (!ininame.exist() && !http_get(http_server, remote, ininame))
|
||
{
|
||
error_box(FR("Errore di trasferimento del file %s"), (const char*)remote);
|
||
modules.destroy(i);
|
||
}
|
||
str = ininame;
|
||
}
|
||
else
|
||
modules.destroy(i);
|
||
}
|
||
modules.pack();
|
||
}
|
||
else //normal patches
|
||
{
|
||
ininame = path;
|
||
ininame.add("??????a.ini");
|
||
list_files(ininame, modules);
|
||
}
|
||
|
||
if (modules.items() > 0) //ordina i moduli come sull'install.ini locale (per avere SY come primo
|
||
{ //modulo e via via gli altri)
|
||
TInstall_ini installini;
|
||
TString_array paragrafi;
|
||
TFilename file;
|
||
|
||
installini.list_paragraphs(paragrafi);
|
||
// rimozione del produttore sull'install.ini locale ora obsoleto..
|
||
installini.remove("Producer");
|
||
|
||
FOR_EACH_ARRAY_ROW(modules, am, arow)
|
||
{
|
||
file = *arow;
|
||
file = file.name();
|
||
int pos = paragrafi.find(file.left(2));
|
||
if (pos <= 0)
|
||
pos = 10000+am;
|
||
TString8 str;
|
||
str.format("%05d", pos); //aggiunge un numero d'ordine sulla sinistra del nome del file..
|
||
arow->insert(str);
|
||
}
|
||
modules.sort(); //..cosi' che la sort (che ordina alfabeticamente) sistemi la lista moduli
|
||
|
||
FOR_EACH_ARRAY_ROW(modules, bm, brow) //rimette i nomi dei moduli a posto (toglie il numero d'ordine)
|
||
brow->ltrim(5);
|
||
}
|
||
//genera le righe dello sheet di installazione
|
||
FOR_EACH_ARRAY_ROW(modules, am, arow)
|
||
{
|
||
TString& ininame = *arow;
|
||
ininame.lower();
|
||
const int pos = ininame.find("a.ini");
|
||
CHECKS(pos >= 6, TR("Configurazione di installazione non valida: "), (const char*)ininame);
|
||
const TString4 module = ininame.mid(pos-6, 2);
|
||
TConfig ini(ininame, module);
|
||
ini.write_protect();
|
||
int r;
|
||
for (r = int(items()-1); r >= 0; r--)
|
||
{
|
||
if (module == row(r).get(C_CODE))
|
||
break;
|
||
}
|
||
|
||
if (r >= 0)
|
||
{
|
||
if (is_visible_patch(ini))
|
||
{
|
||
const TString16 patchversion = ini.get("Versione");
|
||
const int patchlevel = ini.get_int("Patch");
|
||
TToken_string& row = mask_rows.row(r);
|
||
const TString16 release(row.get(C_RELEASE));
|
||
if (patchversion.mid(4) == release.mid(4) // se le versioni corrispondono ...
|
||
&& patchlevel > row.get_int(C_PATCH)) // ..e il patchlevel <20> superiore
|
||
{
|
||
TString4 patch; patch.format("%04d", patchlevel); //aggiunge zeri per avere 3 cifre sempre
|
||
row.add(patch, C_PATCH); // aggiorna il patchlevel mostrato per il modulo
|
||
row.add(ini.get("Data"), C_DATAREL); // aggiorna data di rilascio
|
||
if (row.get_char(C_ISPATCH)<=' ') // se era un modulo ...
|
||
{
|
||
row.add("+", C_ISPATCH); // .....setta la presenza di patches
|
||
row.add(row.get(C_PATCH), C_BASEPATCH); // memorizza patch del modulo
|
||
}
|
||
if (release < patchversion)
|
||
row.add(patchversion, C_RELEASE);
|
||
}
|
||
}
|
||
else
|
||
destroy(r); // Elimina patch di altri OEM erroneamente inserite
|
||
}
|
||
else
|
||
add_module(ini, module, true);
|
||
}
|
||
update_version();
|
||
const bool ok = precheck_modules() > 0;
|
||
|
||
if (!ok)
|
||
error_box(FR("Non e' stato trovato nessun modulo da installare\nin %s"), (const char*)path);
|
||
|
||
return ok;
|
||
}
|
||
|
||
bool TInstaller_mask::do_process(TToken_string& commands) const
|
||
{
|
||
bool ok = true;
|
||
TFilename cmd;
|
||
for (const char* c = commands.get(0); c && ok; c = commands.get())
|
||
{
|
||
cmd = c;
|
||
if (cmd.full())
|
||
{
|
||
TWait_cursor hourglass;
|
||
TExternal_app app(cmd);
|
||
ok = app.run(false,3,true) == 0;
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TInstaller_mask::pre_process(TInstall_ini& ini, const char* module) const
|
||
{
|
||
TAuto_token_string commands(ini.get("PreProcess", module));
|
||
bool ok = do_process(commands);
|
||
return ok;
|
||
}
|
||
|
||
bool TInstaller_mask::post_process(TInstall_ini& ini, const char* module) const
|
||
{
|
||
TAuto_token_string commands(ini.get("PostProcess", module));
|
||
return do_process(commands);
|
||
}
|
||
|
||
bool TInstaller_mask::can_install(const char* module, TInstall_ini& ini)
|
||
{
|
||
ini.set_paragraph(module);
|
||
if (!is_visible_patch(ini))
|
||
return false;
|
||
|
||
TInstall_ini curini;
|
||
if (curini.demo() != ini.demo())
|
||
{
|
||
TString msg;
|
||
msg << TR("Attenzione: Non e' possibile installare la versione ");
|
||
msg << (ini.demo() ? TR("dimostrativa") : TR("normale"));
|
||
msg << TR(" nella cartella della versione ");
|
||
msg << (curini.demo() ? TR("dimostrativa") : TR("normale"));
|
||
return error_box(msg);
|
||
}
|
||
|
||
const TString& version = ini.version(module);
|
||
const word year = version2year(version);
|
||
if (year < 2009)
|
||
return error_box(FR("Il modulo '%s' non ha una versione valida."), module);
|
||
|
||
#ifndef _DEMO_
|
||
if (year > dongle().year_assist())
|
||
{
|
||
if (!update_assistance_year())
|
||
return false;
|
||
}
|
||
#endif
|
||
|
||
TAuto_token_string altri(ini.get("Moduli", module));
|
||
if (xvt_str_compare_ignoring_case(module, "sy") != 0) //SY e' indipendente dagli altri moduli
|
||
{
|
||
if (xvt_str_compare_ignoring_case(module, "ba") != 0 && altri.get_pos("ba") < 0)
|
||
altri.add("ba");
|
||
}
|
||
|
||
bool ok = true;
|
||
TString submodule;
|
||
for (const char* mod = altri.get(0); mod && ok; mod = altri.get())
|
||
{
|
||
submodule = mod;
|
||
if (submodule.len() == 2)
|
||
{
|
||
if (curini.get("Versione", submodule).empty())
|
||
{
|
||
TString msg;
|
||
msg.format(FR("L'installazione del modulo %s richiede la presenza del modulo %s."),
|
||
(const char*)module, (const char*)submodule);
|
||
msg << '\n' << TR("Si desidera procedere alla sua installazione?");
|
||
ok = yesno_box(msg);
|
||
if (ok)
|
||
ok = install(submodule, 0);
|
||
}
|
||
}
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
int TInstaller_mask::needs_reboot(const TFilename& file) const
|
||
{
|
||
char fname[_MAX_FNAME], ext[_MAX_EXT];
|
||
xvt_fsys_parse_pathname(file, NULL, NULL, fname, ext, NULL);
|
||
|
||
int underscore = NONE;
|
||
if (xvt_str_compare_ignoring_case(ext, "exe") == 0)
|
||
{
|
||
if (xvt_str_compare_ignoring_case(fname, "ba0") == 0)
|
||
underscore = NEW_MENUPRG; else
|
||
if (xvt_str_compare_ignoring_case(fname, "ba1") == 0)
|
||
underscore = NEW_INSTALLER;
|
||
} else
|
||
if (xvt_str_compare_ignoring_case(ext, "dll") == 0)
|
||
underscore = NEW_DLL; else
|
||
if (xvt_str_compare_ignoring_case(ext, "men") == 0)
|
||
underscore = NEW_MENU; else
|
||
if (xvt_str_compare_ignoring_case(ext, "trr") == 0 || xvt_str_compare_ignoring_case(ext, "dir") == 0)
|
||
underscore = NEW_TRR;
|
||
return underscore;
|
||
}
|
||
|
||
// Controlla se un file puo' essere scompattato.
|
||
// Attenzione: dninst.zip e' un falso zip
|
||
bool TInstaller_mask::is_zip_file(const TFilename& n) const
|
||
{
|
||
bool yes = xvt_str_compare_ignoring_case(n.ext(), "zip") == 0 &&
|
||
xvt_str_compare_ignoring_case(n.name_only(), "dninst") != 0;
|
||
return yes;
|
||
}
|
||
|
||
bool TInstaller_mask::copy_file(const TFilename& src, const TFilename& dst) const
|
||
{
|
||
// Crea la cartella di destinazione se necessario
|
||
const char* dstdir = dst.path();
|
||
if (*dstdir && !xvt_fsys_mkdir(dstdir))
|
||
return error_box(FR("Impossibile creare la cartella %s"), dst.path());
|
||
|
||
// Copia veramente il file
|
||
return ::fcopy(src, dst);
|
||
}
|
||
|
||
// sposta il file dal direttorio temporaneo a quello passato come destinazione
|
||
bool TInstaller_mask::move_file(const TFilename& src, const TFilename& dst) const
|
||
{
|
||
TFilename dest = dst;
|
||
const int reboot = needs_reboot(dest);
|
||
if ((reboot & NEW_SYS)!=0 && dst.exist())
|
||
{
|
||
dest.rtrim(1);
|
||
dest << '_';
|
||
}
|
||
|
||
const bool is_zip = is_zip_file(src);
|
||
const long filesize = fsize(src) * (is_zip ? 4 : 1);
|
||
|
||
if (xvt_fsys_test_disk_free_space(dest.path(), filesize) == 0)
|
||
return error_box(TR("Lo spazio disponibile e' insufficiente!"));
|
||
|
||
const bool write_ok = copy_file(src, dest);
|
||
if (write_ok && is_zip)
|
||
aga_unzip(src, dest.path());
|
||
|
||
if (write_ok)
|
||
src.fremove();
|
||
|
||
if (write_ok)
|
||
{
|
||
(int&)_reboot_program |= reboot; // Skip const!
|
||
}
|
||
return write_ok;
|
||
}
|
||
|
||
bool TInstaller_mask::move_module(const TString& module, TInstall_ini& ini, bool update) const
|
||
{
|
||
bool ok = true;
|
||
|
||
TFilename tempdir; tempdir.tempdir();
|
||
const TString& destdir = get(F_CURPATH);
|
||
|
||
TString_array list;
|
||
ini.build_list(module, list);
|
||
FOR_EACH_ARRAY_ROW(list, f, file)
|
||
{
|
||
TFilename src = tempdir;
|
||
src.add(file->get(0));
|
||
if (update)
|
||
{
|
||
TFilename dst = destdir;
|
||
dst.add(file->get(0));
|
||
const bool move_ok = move_file(src, dst);
|
||
if (!move_ok)
|
||
ok = update = false;
|
||
}
|
||
if (!update)
|
||
src.fremove();
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
bool TInstaller_mask::copy_tree(const char* src_study, const char* dst_study) const
|
||
{
|
||
xvt_fsys_save_dir();
|
||
TFilename mask(src_study); mask.add("*.");
|
||
SLIST dlist = xvt_fsys_list_files(DIR_TYPE, mask, TRUE);
|
||
xvt_fsys_restore_dir();
|
||
TProgind pd(xvt_slist_count(dlist), TR("Copia cartelle"), true, true);
|
||
|
||
TString msg; // Messaggio di progresso
|
||
|
||
bool go_on = true;
|
||
for (SLIST_ELT d = xvt_slist_get_first(dlist); d && go_on; d = xvt_slist_get_next(dlist, d))
|
||
{
|
||
if (!pd.addstatus(1))
|
||
{
|
||
go_on = false;
|
||
break;
|
||
}
|
||
|
||
const TFilename dir = xvt_slist_get(dlist, d, NULL);
|
||
|
||
TString name = dir.name(); name.lower();
|
||
if (name == "cesp") // Ignora la vetusta cartella Cespiti in FoxPro
|
||
continue;
|
||
|
||
msg.cut(0) << TR("Copia di ") << name;
|
||
pd.set_text(msg);
|
||
|
||
mask = dir; mask.add("*.*");
|
||
TString_array files; list_files(mask, files);
|
||
|
||
TProgind pi(files.items(), "Copia file", true, true);
|
||
|
||
TFilename dst;
|
||
FOR_EACH_ARRAY_ROW(files, i, f)
|
||
{
|
||
if (!pi.addstatus(1))
|
||
{
|
||
go_on = false;
|
||
break;
|
||
}
|
||
TFilename src(*f);
|
||
TString16 ext(src.ext()); ext.lower();
|
||
if (ext != "zip" && ext != "rar" && ext != "mdb" && ext != "inf")
|
||
{
|
||
msg.cut(0) << TR("Copia di ") << src;
|
||
pi.set_text(msg);
|
||
|
||
dst = dst_study;
|
||
dst.add(name);
|
||
dst.add(src.name());
|
||
copy_file(src, dst);
|
||
}
|
||
}
|
||
}
|
||
xvt_slist_destroy(dlist);
|
||
|
||
return go_on;
|
||
}
|
||
|
||
void TInstaller_mask::backup() const
|
||
{
|
||
TFilename src = firm2dir(-1);
|
||
if (!isalnum(src.right(1)[0]))
|
||
src.rtrim(1);
|
||
TFilename dst(src);
|
||
dst << ' ' << TDate(TODAY).date2ansi(); // Lo spazio rende inutilizzabile lo studio
|
||
|
||
TToken_string msg(256, '\n');
|
||
msg.add(TR("Si consiglia creare una copia dello studio ")); msg << src.name();
|
||
msg.add(TR("nella cartella ")); msg << dst;
|
||
msg.add(TR("L'operazione potrebbe richiedere alcuni minuti."));
|
||
msg.add("");
|
||
msg.add(TR("Si desidera effetture la copia?"));
|
||
if (yesno_box(msg))
|
||
copy_tree(src, dst);
|
||
}
|
||
|
||
|
||
KEY TInstaller_mask::askdisk(TString & path, TFilename & cmdline, int d, int dischi, const char * modulo)
|
||
{
|
||
TMask retry_mask(TR("Inserimento disco"),1,80,10);
|
||
|
||
retry_mask.add_static((F_PATH==101 ? 102:101),0,
|
||
format(FR("Inserire il disco %d di %d del modulo '%s' nell'unit<69>"), d, dischi, modulo)
|
||
,2,2);
|
||
retry_mask.add_static(F_PATH+3,0,TR("oppure indicare un percorso diverso"),2,3);
|
||
|
||
retry_mask.add_string(F_PATH,0,"",2,5,48);
|
||
retry_mask.add_button(DLG_OK,0,TR("Riprova"),-12,7,9,2);
|
||
retry_mask.add_button(DLG_QUIT,0,"",-22,7,9,2);
|
||
retry_mask.set(F_PATH,path);
|
||
KEY k;
|
||
do {
|
||
if ((k=retry_mask.run())==K_QUIT )
|
||
break;
|
||
if (!retry_mask.get(F_PATH).blank())
|
||
{
|
||
if (fexist(retry_mask.get(F_PATH)))
|
||
{
|
||
TString16 tmpname(cmdline.name() );
|
||
cmdline= path = retry_mask.get(F_PATH);
|
||
cmdline.add(tmpname);
|
||
break;
|
||
}
|
||
else
|
||
error_box(TR("Il percorso indicato non e' valido"));
|
||
}
|
||
} while (true);
|
||
return k;
|
||
}
|
||
|
||
//rimozione da disco dei files da eliminare indicati nei paragrafi kill..
|
||
//..e successivo aggiornamento dell'install.ini in modo da non avere pi<70> tra i piedi i files killati
|
||
void TInstaller_mask::kill_files()
|
||
{
|
||
//apre l'install.ini locale per effettuare l'aggiornamento
|
||
TInstall_ini ini;
|
||
//giro su tutti i sottomoduli di tipo 99 con l'elenco dei files da uccidere
|
||
TString_array paragraph_names;
|
||
ini.list_paragraphs(paragraph_names);
|
||
|
||
FOR_EACH_ARRAY_ROW(paragraph_names, nriga, riga)
|
||
{
|
||
//interessano solo i paragrafi con le killer list
|
||
if (riga->ends_with("99") && ini.set_paragraph(*riga))
|
||
{
|
||
TString_array killed;
|
||
|
||
TToken_string rigaini;
|
||
TFilename filetokill;
|
||
for (int k = 0;; k++)
|
||
{
|
||
rigaini = ini.get("Kill", NULL, k, "");
|
||
if (rigaini.empty())
|
||
break;
|
||
filetokill = rigaini.get(0);
|
||
if (filetokill.find('*') >= 0 || filetokill.find('?') >= 0)
|
||
{
|
||
TString_array filelist;
|
||
list_files (filetokill, filelist);
|
||
FOR_EACH_ARRAY_ROW(filelist, r, file)
|
||
{
|
||
filetokill = *file;
|
||
if (filetokill.exist())
|
||
filetokill.fremove();
|
||
killed.add(filetokill);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (filetokill.exist())
|
||
filetokill.fremove();
|
||
killed.add(filetokill);
|
||
}
|
||
} //for(int k=0...
|
||
|
||
for (int s = 0; s <= 9 && !killed.empty(); s++)
|
||
{
|
||
const TString4 mod = riga->left(2);
|
||
const int cicli = mod == "ba" ? 2 : 1;
|
||
for (int c = 1; c <= cicli; c++)
|
||
{
|
||
TString4 module = c == 1 ? mod : "sy";
|
||
module << s;
|
||
TAssoc_array& vars = ini.list_variables(module);
|
||
FOR_EACH_ASSOC_STRING(vars, hobj, key, str)
|
||
{
|
||
const int idx = killed.find(str);
|
||
if (idx >= 0)
|
||
{
|
||
ini.remove(key);
|
||
killed.destroy(idx, true);
|
||
}
|
||
}
|
||
}
|
||
} //for (int s...
|
||
} //if (riga->ends_with...
|
||
} //FOR_EACH_ARRAY_ROW(...
|
||
}
|
||
|
||
bool TInstaller_mask::install(const TString& module, int patchlevel)
|
||
{
|
||
bool cancelled = false;
|
||
bool ok = false;
|
||
TString msg; // stringa per i messaggi
|
||
TString16 lastrelease; // release che sto installando
|
||
int lastpatch = patchlevel; // patchlevel che sto installando
|
||
|
||
TFilename path ;
|
||
TString http_server;
|
||
TFilename http_path;
|
||
|
||
const bool internet = get_patches_path(path);
|
||
if (internet)
|
||
parse_internet_path(http_server,http_path );
|
||
|
||
const bool is_a_patch = (patchlevel > 0);
|
||
//file .ini con le info di installazione (es. bainst.ini o ba0883.ini)
|
||
TFilename remote_ininame = path;
|
||
remote_ininame.add(module);
|
||
|
||
//completa il nome del file .ini controllando se <20> una patch (es. ba0883a.ini) o se <20> un pacco (es. bainst.ini)
|
||
if (is_a_patch)
|
||
{
|
||
TString16 name;
|
||
name.format("%04da.ini", patchlevel);
|
||
remote_ininame << name;
|
||
}
|
||
else
|
||
remote_ininame << "inst.ini";
|
||
|
||
if (internet && !remote_ininame.exist())
|
||
{
|
||
TFilename remote = remote_ininame.name();
|
||
remote.insert(http_path, 0);
|
||
http_get(http_server, remote, remote_ininame);
|
||
}
|
||
|
||
if (remote_ininame.exist())
|
||
{
|
||
// esiste un particolare .ini con formato XXinst.ini (moduli) o con XX9999a.ini (patch)
|
||
//----------------------------------------------
|
||
// (INSTALLAZIONE DA DIRECTORY CON FILES .ZIP)
|
||
//----------------------------------------------
|
||
//remote_ini <20> il file .ini con le info di installazione (es. ba0883a.ini, bainst.ini)
|
||
TInstall_ini* remote_ini = new TInstall_ini(remote_ininame);
|
||
remote_ini->write_protect();
|
||
lastpatch = remote_ini->get_int("Patch", module);
|
||
lastrelease = remote_ini->get("Versione", module);
|
||
|
||
//se non pu<70> installare il modulo chiude il remote_ini
|
||
if (!can_install(module, *remote_ini))
|
||
{
|
||
delete remote_ini;
|
||
return false;
|
||
}
|
||
|
||
//antico controllo del numero di dischetti (ora sempre = 1)
|
||
const int dischi = remote_ini->get_int("Dischi", module);
|
||
ok = dischi > 0;
|
||
if (!ok)
|
||
return error_box(FR("Impossibile determinare il numero dei dischetti in %s"), remote_ininame.name());
|
||
else
|
||
{
|
||
if (patchlevel == 0)
|
||
ok = pre_process(*remote_ini, module);
|
||
if (!ok)
|
||
{
|
||
delete remote_ini;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// DECOMPRESSIONE
|
||
// ----------------
|
||
// viene decompresso il file .zip collegato al file remote_ini (es. ba0883a1.zip, bainst.zip)
|
||
|
||
TProgind* pi = NULL;
|
||
if (dischi > 1)
|
||
{
|
||
msg = TR("Decompressione");
|
||
if (is_a_patch)
|
||
msg << TR(" della patch ") << patchlevel ;
|
||
msg << TR(" del modulo '") << module << TR("' in corso...");
|
||
pi = new TProgind(dischi, msg, false, true);
|
||
}
|
||
|
||
TFilename tempdir;
|
||
tempdir.tempdir();
|
||
|
||
// File tottale dei vari sotto-zip
|
||
TFilename totti = tempdir;
|
||
totti.add(module);
|
||
totti.ext("zip");
|
||
|
||
//si costruisce il nome dello zip
|
||
for (int d = 1; d <= dischi && ok; d++)
|
||
{
|
||
TFilename chunk = path;
|
||
chunk.add(module);
|
||
if (patchlevel > 0)
|
||
{
|
||
TString8 name;
|
||
name.format("%04da", patchlevel);
|
||
chunk << name;
|
||
}
|
||
else
|
||
chunk << "inst";
|
||
chunk << d << ".zip";
|
||
|
||
if (internet && !chunk.exist())
|
||
{
|
||
TFilename remote = chunk.name();
|
||
remote.insert(http_path, 0);
|
||
if (!http_get(http_server, remote, chunk))
|
||
error_box(FR("Errore di trasferimento del file '%s'"), (const char*)remote);
|
||
}
|
||
|
||
//antichi controlli in caso di multidischetto
|
||
ok = chunk.exist();
|
||
if (!ok && !internet) // Chiedi cambio disco (solo se non sta scaricando da internet)
|
||
{
|
||
while (!ok)
|
||
{
|
||
if (askdisk(path, chunk, d, dischi, (const char*)remote_ini->get("Descrizione")) == K_QUIT)
|
||
break;
|
||
ok = chunk.exist();
|
||
if (!ok)
|
||
message_box(FR("Impossibile trovare il file '%s'"), (const char*)chunk);
|
||
}
|
||
}
|
||
|
||
if (ok)
|
||
{
|
||
const long required = fsize(chunk) * (dischi - d + 1) * 4;
|
||
if (!xvt_fsys_test_disk_free_space(tempdir, required))
|
||
{
|
||
ok = yesno_box(TR("Lo spazio su disco potrebbe essere insufficiente:\nSi desidera continuare ugualmente?"));
|
||
}
|
||
}
|
||
|
||
if (ok)
|
||
::fcopy(chunk, totti, d > 1); // Somma il chunk al totale
|
||
}
|
||
if (pi != NULL)
|
||
{
|
||
delete pi;
|
||
pi = NULL;
|
||
}
|
||
|
||
//scompattamento vero e proprio dello zip
|
||
aga_unzip(totti, tempdir); // Scompatta il file totale zip
|
||
totti.fremove(); // Elimina il file totale zip
|
||
|
||
|
||
// TRASFERIMENTO
|
||
// -----------------
|
||
if (ok)
|
||
{
|
||
// si assicura che sia leggibile il .ini del primo disco
|
||
do
|
||
{
|
||
TFilename cmdline = path;
|
||
cmdline.add(remote_ininame.name());
|
||
ok = cmdline.exist();
|
||
if (!ok)
|
||
{
|
||
if (askdisk(path, cmdline, 1, dischi, (const char*)remote_ini->get("Descrizione")) == K_QUIT)
|
||
break;
|
||
ok = fexist(cmdline);
|
||
if (!ok)
|
||
message_box(FR("Impossibile trovare %s\n"), (const char*)cmdline);
|
||
else
|
||
{
|
||
delete remote_ini;
|
||
remote_ini = new TInstall_ini (cmdline);
|
||
}
|
||
}
|
||
} while (!ok);
|
||
|
||
if (ok)
|
||
{
|
||
TWait_cursor hourglass;
|
||
msg.cut(0);
|
||
msg << TR("Aggiornamento del modulo '") << module << TR("' in corso...");
|
||
xvtil_statbar_set(msg);
|
||
ok = move_module(module, *remote_ini, true);
|
||
|
||
if (ok)
|
||
{
|
||
TAuto_token_string altri(remote_ini->get("Moduli", module));
|
||
FOR_EACH_TOKEN(altri, mod)
|
||
{
|
||
const TString16 submod = mod;
|
||
if (submod.len() > 2) // sposta sottomoduli esterni
|
||
{
|
||
bool upd = ok;
|
||
if (ok)
|
||
{
|
||
TInstall_ini local_cur_ini;
|
||
const TString16 curver = local_cur_ini.version(submod);
|
||
const int curpatch = local_cur_ini.patch(submod);
|
||
const TString16 reqver = remote_ini->version(submod);
|
||
const int reqpatch = remote_ini->patch(submod);
|
||
|
||
int distance = compare_version(reqver, reqpatch, curver, curpatch);
|
||
upd = distance > 0;
|
||
}
|
||
ok &= move_module(submod, *remote_ini, upd);
|
||
if (upd && ok) // marca sull'install.ini di destinazione l'avvenuta installazione del sottomodulo "esterno"
|
||
remote_ini->export_paragraph(submod, TInstall_ini::default_name(), !is_a_patch);
|
||
}
|
||
}
|
||
}
|
||
xvtil_statbar_set("");
|
||
} //if(ok)..
|
||
} //if(ok)..
|
||
if (ok) // marca sull'install.ini di destinazione l'avvenuta installazione del modulo
|
||
remote_ini->export_module_paragraphs(module, TInstall_ini::default_name(), !is_a_patch);
|
||
} // installazione da directory con zip
|
||
else
|
||
if (!is_a_patch)
|
||
{
|
||
// non c'e' il .ini del modulo ma un unico "install.ini" (es. aggiornamento client)
|
||
//------------------------------------------------
|
||
// (INSTALLAZIONE DA DIRECTORY CON ESEGUIBILI)
|
||
//------------------------------------------------
|
||
remote_ininame = path;
|
||
remote_ininame.add(TInstall_ini::default_name());
|
||
ok = fexist(remote_ininame);
|
||
if (ok)
|
||
{
|
||
TInstall_ini ini(remote_ininame);
|
||
ini.write_protect();
|
||
lastpatch = ini.get_int("Patch", module);
|
||
lastrelease = ini.get("Versione", module);
|
||
if (!can_install(module, ini))
|
||
return false;
|
||
|
||
TString_array list;
|
||
const int files = ini.build_complete_list(module, list);
|
||
if (files > 0)
|
||
{
|
||
if (patchlevel == 0)
|
||
ok = pre_process(ini, module);
|
||
|
||
if (ok)
|
||
{
|
||
msg.cut(0) << TR("Copia del modulo ") << module;
|
||
TProgind pi(files, msg, true, true);
|
||
TFilename src, dst;
|
||
for (int f = 0; f < files && ok; f++)
|
||
{
|
||
pi.addstatus(1);
|
||
dst = list.row(f).get(0);
|
||
dst.lower();
|
||
src = path;
|
||
src.add(dst);
|
||
const int reboot = needs_reboot(dst);
|
||
if ((reboot & NEW_SYS)!=0 && dst.exist())
|
||
{
|
||
dst.rtrim(1);
|
||
dst << '_';
|
||
}
|
||
ok = copy_file(src, dst);
|
||
|
||
if (ok && is_zip_file(src))
|
||
aga_unzip(src, dst.path());
|
||
|
||
if (ok && reboot != NONE)
|
||
_reboot_program |= reboot;
|
||
|
||
cancelled = pi.iscancelled();
|
||
}
|
||
ok &= !cancelled;
|
||
}
|
||
|
||
if (ok) // marca sull'install.ini di destinazione l'avvenuta installazione del modulo
|
||
ini.export_module_paragraphs(module, ini.default_name(), true);
|
||
} // controllo esistenza lista di file non vuota per questo modulo
|
||
} // controllo esistenza install.ini
|
||
} // fine installazione da directory con eseguibili
|
||
|
||
if (ok)
|
||
{
|
||
{
|
||
TInstall_ini ini;
|
||
ini.set("Data", TDate(TODAY), module);
|
||
ini.update_prices(remote_ininame);
|
||
}
|
||
// Non togliere le parentesi graffe soprastanti per permettere l'aggiornamento fisico del .ini (CON LA CHIAMATA DEL DISTRUTTORE)
|
||
update_version();
|
||
}
|
||
|
||
|
||
if (ok && patchlevel == 0) // Se installo un modulo pricipale ...
|
||
{
|
||
// ... installo DOPO tutte le patches successive
|
||
install_patches(module, lastrelease, lastpatch);
|
||
TInstall_ini ini;
|
||
ok &= post_process(ini, module);
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
bool TInstaller_mask::get_patches_path(TFilename& path) const
|
||
{
|
||
const TEdit_field& www = efield(F_WEB);
|
||
path = www.get();
|
||
if (www.active() && path.full() && is_internet_path(path))
|
||
{
|
||
path.tempdir();
|
||
path.add("www");
|
||
make_dir(path); //crea la directory temporanaea di installazione dove depositare e scompattare gli zip
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
path = get(F_PATH);
|
||
// Toglie l'eventual slash finale
|
||
const char last = path.right(1)[0];
|
||
if (last == '/' || last == '\\')
|
||
path.rtrim(1);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void TInstaller_mask::parse_internet_path(TString & http_server, TFilename &http_path) const
|
||
{
|
||
http_server = get(F_WEB);
|
||
if (http_server.blank())
|
||
{
|
||
http_server = http_default_path();
|
||
((TMask*)this)->set(F_WEB, http_server);
|
||
}
|
||
|
||
if (http_server.starts_with("http://"))
|
||
http_server.ltrim(7);
|
||
|
||
const int slash = http_server.find('/');
|
||
if (slash > 0)
|
||
{
|
||
http_path = http_server.mid(slash);
|
||
http_server.cut(slash);
|
||
}
|
||
|
||
//aggiunge lo slash finale se l'utonto l'ha omesso
|
||
if (!http_path.ends_with("/"))
|
||
http_path << '/';
|
||
|
||
//e' un server redirezionato?
|
||
http_isredirected_server(http_server, http_path);
|
||
}
|
||
|
||
bool TInstaller_mask::install_patches(const TString& module, const TString& lastrelease, int lastpatch, bool only_newer)
|
||
{
|
||
bool ok = true;
|
||
TString_array modules;
|
||
TFilename ininame;
|
||
get_patches_path(ininame);
|
||
|
||
ininame.add(module);
|
||
ininame << "????a.ini";
|
||
modules.destroy();
|
||
list_files(ininame, modules);
|
||
modules.sort();
|
||
FOR_EACH_ARRAY_ROW(modules, am, arow)
|
||
{
|
||
TString& ininame = *arow;
|
||
ininame.lower();
|
||
const int pos = ininame.find("a.ini");
|
||
CHECKS(pos >= 6, "Invalid installation configuration: ", (const char*)ininame);
|
||
const TString16 patchmodule = ininame.mid(pos-6, 2);
|
||
TConfig ini(ininame, patchmodule);
|
||
const int patchlevel = ini.get_int("Patch");
|
||
const TString16 patchversion = ini.get("Versione");
|
||
if (ok && lastrelease.mid(4) == patchversion.mid(4) // installa solo le patch della stessa ver..
|
||
&& (only_newer ? lastpatch < patchlevel : lastpatch <= patchlevel)) // ... e patch superiore o uguale (reinstalla l'ultima patch)
|
||
ok = install(module, patchlevel);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TInstaller_mask::update_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
TInstaller_mask& m = (TInstaller_mask&)f.mask();
|
||
m.autoload();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TInstaller_mask::path_handler(TMask_field& fld, KEY key)
|
||
{
|
||
bool ok = true;
|
||
if (key == K_TAB && fld.focusdirty())
|
||
{
|
||
TFilename path = fld.get();
|
||
if (path.not_empty())
|
||
{
|
||
if (path.len() == 2 && isalpha(path[0]) && path[1] == ':')
|
||
{
|
||
path << SLASH;
|
||
fld.set(path);
|
||
}
|
||
if (path.exist() || ::is_internet_path(path))
|
||
_curr_mask->autoload();
|
||
else
|
||
ok = fld.error_box(TR("Specificare un percorso valido"));
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TInstaller_mask::web_handler(TMask_field& fld, KEY key)
|
||
{
|
||
bool ok = true;
|
||
if (key == K_TAB && fld.focusdirty())
|
||
{
|
||
TFilename path = fld.get();
|
||
if (path.not_empty())
|
||
{
|
||
if (!path.ends_with("/"))
|
||
{
|
||
path << '/';
|
||
fld.set(path);
|
||
}
|
||
ok = ::is_internet_path(path);
|
||
if (!ok)
|
||
ok = fld.error_box(TR("Specificare un indirizzo valido"));
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
|
||
// Aggiorna l'install.ini con eventuali modifiche dell'utente su dispath e/o webpath
|
||
// Decisivo in caso di cambio path d'installazione
|
||
// Serve a setup (deve essere chiamata in caso di esecuzioni passive di setup, tipo -uw, -uw)
|
||
void TInstaller_mask::update_disk_and_web_path()
|
||
{
|
||
TInstall_ini ini;
|
||
ini.set("DiskPath", get(F_PATH));
|
||
ini.set("WebPath", get(F_WEB));
|
||
}
|
||
|
||
void TInstaller_mask::install_selection()
|
||
{
|
||
TString_array& arr = rows_array();
|
||
|
||
int nModules = 0;
|
||
{
|
||
FOR_EACH_ARRAY_ROW(arr, r, row)
|
||
{
|
||
if (checked(r))
|
||
nModules++;
|
||
}
|
||
}
|
||
|
||
TProgind pi(nModules, "Installazione", true, true);
|
||
|
||
FOR_EACH_ARRAY_ROW(arr, r, row) if (checked(r))
|
||
{
|
||
if (!pi.addstatus(1))
|
||
break;
|
||
|
||
const TString newver = row->get(C_RELEASE);
|
||
if (newver.blank())
|
||
{
|
||
check(r, false);
|
||
continue;
|
||
}
|
||
|
||
const TString4 modulo = row->get(C_CODE);
|
||
const TString modesc = dongle().module_name2desc(modulo);
|
||
const int newpatch = row->get_int(C_PATCH);
|
||
const TString oldver = row->get(C_CURRRELEASE);
|
||
const int oldpatch = row->get_int(C_CURRPATCH);
|
||
|
||
pi.set_text(format(FR("Installazione modulo '%s'"), (const char*)modesc));
|
||
if (version2year(newver) < 2008)
|
||
{
|
||
error_box(FR("Il modulo '%s' non ha una versione valida."), (const char*)modesc);
|
||
continue;
|
||
}
|
||
|
||
bool ok = true;
|
||
bool is_patch = row->get_char(C_ISPATCH) == 'X';
|
||
bool has_patch = row->get_char(C_ISPATCH) == '+';
|
||
const int cmp = compare_version(oldver, oldpatch, newver, newpatch);
|
||
|
||
//versione e patch coincidono
|
||
if (cmp == 0)
|
||
ok = noyes_box(FR("Si desidera reinstallare la versione %s.%d del modulo '%s' ?"), (const char*)newver, newpatch, (const char*)modesc);
|
||
|
||
//ci sono ANCHE i pacchi
|
||
if (!is_patch && cmp > 0)
|
||
{
|
||
TString256 msg;
|
||
msg.format(FR("Si desidera ritornare alla versione %s.%d del modulo '%s' ?\nAttenzione: non e' garantito il corretto\nfunzionamento di tutti i programmi!"), (const char*)newver, newpatch, (const char*)modesc);
|
||
ok = noyes_box(msg);
|
||
}
|
||
|
||
//ci sono SOLO patch da installare
|
||
if (ok && is_patch)
|
||
{
|
||
// installo le patch solo se esiste gi<67> un modulo installato della stessa versione
|
||
if (!oldver.blank() )
|
||
{
|
||
if (compare_version(oldver, 0, newver, 0)) //controlla SOLO la versione indipendentemente dall'anno!
|
||
ok = error_box(FR("Il modulo '%s' installato ha versione %s:\nimpossibile installare le patch della versione %s"),(const char *)modulo,(const char *)oldver,(const char *)newver);
|
||
} else
|
||
if (newpatch < oldpatch)
|
||
{
|
||
TString256 msg;
|
||
msg.format(FR("Si desidera ritornare alla patch %s.%d del modulo '%s' ?\nAttenzione: non e' garantito il corretto\nfunzionamento di tutti i programmi!"), (const char*)newver, newpatch, (const char*)modesc);
|
||
ok = noyes_box(msg);
|
||
}
|
||
} //if(ok&&is_patch...
|
||
|
||
if (ok)
|
||
{
|
||
if (has_patch)
|
||
{
|
||
if (newver == oldver && newpatch >= oldpatch)
|
||
{
|
||
const int basepatch = row->get_int(C_BASEPATCH);
|
||
if (oldpatch >= basepatch)
|
||
is_patch = !noyes_box(FR("Si desidera reinstallare l'intero modulo '%s'?"
|
||
"\nRispondendo NO verranno installate le sole patch"),
|
||
(const char *)modesc);
|
||
else
|
||
is_patch = false; // Quando la versione installata precede la patch base devo reinstallare il modulo!
|
||
}
|
||
}
|
||
|
||
TFilename path;
|
||
const bool internet = get_patches_path(path);
|
||
|
||
//richiesto aggiornamento da disco del modulo SY o del modulo SR da manutenzione/installazione moduli!
|
||
if (modulo == "sy" || modulo == "sr")
|
||
{
|
||
if (!internet)
|
||
{
|
||
bool file_copied = false;
|
||
//trova il path della directory setup che e' nell'area con gli zip del cd
|
||
TFilename disk_path = path;
|
||
disk_path.add("setup/");
|
||
TString_array ar;
|
||
const int items = disk_path.exist() ? list_files(disk_path, ar) : 0;
|
||
if (items > 0)
|
||
{
|
||
//copia la dir setup dal disco sovrascrivendo eventuali files gia' presenti
|
||
make_dir("setup");
|
||
TFilename local_file, remote_file;
|
||
FOR_EACH_ARRAY_ROW(ar, r, row)
|
||
{
|
||
local_file = row->mid(path.len() + 1);
|
||
remote_file = *row;
|
||
file_copied = fcopy(remote_file, local_file); //occhio alle maiuscole!!!!
|
||
}
|
||
}
|
||
|
||
update_disk_and_web_path(); //aggiorna l'install.ini
|
||
//lancia setup in modalita' aggiornamento da disco
|
||
if (test_station_type() == 3)
|
||
_setup_run = xvt_sys_execute("setup\\setup.exe -uc", false, false) !=0;
|
||
else
|
||
_setup_run = xvt_sys_execute("setup\\setup.exe -ud", false, false) !=0;
|
||
}
|
||
//richiesto aggiornamento via web del modulo SY da manutenzione/installazione moduli!
|
||
else
|
||
{
|
||
bool file_copied = false;
|
||
//trova l'indirizzo web completo
|
||
TString http_server;
|
||
TFilename http_path;
|
||
parse_internet_path(http_server, http_path);
|
||
//copia la dir setup dalla remote dir sovrascrivendo eventuali files gia' presenti
|
||
http_path.add("setup/");
|
||
TString_array ar;
|
||
http_dir(http_server, http_path, ar);
|
||
if (ar.items() > 0)
|
||
{
|
||
make_dir("setup");
|
||
TFilename local_file, remote_file;
|
||
FOR_EACH_ARRAY_ROW(ar, r, row)
|
||
{
|
||
local_file = "setup";
|
||
local_file.add(*row);
|
||
remote_file = http_path;
|
||
remote_file.add(*row);
|
||
//via web NON deve copiare oem.ini perch<63> NON deve poter cambiare il reseller (solo via disco sar<61>..
|
||
//..possibile)
|
||
const bool is_oem_ini = xvt_str_compare_ignoring_case(remote_file.name(), "oem.ini") == 0;
|
||
if (is_oem_ini)
|
||
{
|
||
const int old_oem = xvt_sys_get_profile_int(local_file, "MAIN", "OEM", -1);
|
||
file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!!
|
||
const int new_oem = xvt_sys_get_profile_int(local_file, "MAIN", "OEM", -1);
|
||
if (new_oem != old_oem)
|
||
{
|
||
TString4 str_oem; str_oem << ' ' << old_oem;
|
||
xvt_sys_set_profile_string(local_file, "MAIN", "OEM", str_oem);
|
||
}
|
||
}
|
||
else
|
||
file_copied = http_get(http_server, remote_file, local_file); //occhio alle maiuscole!!!!
|
||
}
|
||
}
|
||
update_disk_and_web_path(); //aggiorna l'install.ini
|
||
//lancia setup in modalita' aggiornamento web
|
||
_setup_run = xvt_sys_execute("setup\\setup.exe -uw", false, false) != 0;
|
||
}
|
||
if (_setup_run) //se riesce a lanciare setup.exe...
|
||
{
|
||
//si suicida...Banzai!
|
||
uncheck(r);
|
||
send_key(K_SPACE, DLG_QUIT);
|
||
return;
|
||
}
|
||
}
|
||
|
||
//installa solo le patch del modulo...
|
||
if (is_patch)
|
||
{
|
||
ok = install_patches(modulo, oldver, oldpatch, false) ; // installa l'ultima patch
|
||
if (!ok)
|
||
message_box(TR("Impossibile installare le patch del modulo '%s'"),(const char *)modesc);
|
||
}
|
||
else //..installa anche il pacco del modulo
|
||
{
|
||
ok = install(modulo, 0); // installa il modulo
|
||
}
|
||
if (ok)
|
||
{
|
||
_installed = true; // Setta il flag di almeno un modulo installato
|
||
uncheck(r); //finalmente unchecka i moduli installati
|
||
}
|
||
} //if(ok)...
|
||
else
|
||
uncheck(r); // se non ci sono patch o moduli -> uncheck
|
||
} //FOR_EACH_ARRAY_ROW(arr...
|
||
|
||
//aggiorna definitivamente i path su install.ini
|
||
update_disk_and_web_path();
|
||
//accoppa i files nelle kill lists e aggiorna install.ini
|
||
kill_files();
|
||
//serve per togliere il check al modulo 'sy' quando viene installato
|
||
force_update();
|
||
}
|
||
|
||
bool TInstaller_mask::install_handler(TMask_field& fld, KEY key)
|
||
{
|
||
if (key == K_SPACE)
|
||
{
|
||
if (_curr_mask->items() == 1)
|
||
_curr_mask->check(0);
|
||
const bool check_on = _curr_mask->check_enabled();
|
||
_curr_mask->enable_check(true);
|
||
const bool some = _curr_mask->one_checked();
|
||
_curr_mask->enable_check(check_on);
|
||
if (some)
|
||
_curr_mask->install_selection();
|
||
else
|
||
error_box(TR("Selezionare uno o piu' moduli da installare."));
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
bool TInstaller_mask::tutti_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
TInstaller_mask & m=(TInstaller_mask &) f.mask();
|
||
if (m.check_enabled())
|
||
{
|
||
if (m.one_checked())
|
||
m.uncheck(-1);
|
||
else
|
||
m.precheck_modules(false);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TInstaller_mask::on_key(KEY key)
|
||
{
|
||
bool ok = true;
|
||
switch (key)
|
||
{
|
||
case K_F7: autoload(); break;
|
||
case K_F8: field(DLG_USER).on_hit(); break;
|
||
default : ok = TArray_sheet::on_key(key); break;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
//metodo per controllare se la directory indicata contiene una installazione buona di campo
|
||
bool TInstaller_mask::is_program_dir(const TFilename& path)
|
||
{
|
||
bool ok = false;
|
||
TFilename work_path = path;
|
||
|
||
//controlla l'esistenza di alcuni files chiave di campo
|
||
work_path.add("install.ini");
|
||
if (work_path.exist())
|
||
{
|
||
work_path = path;
|
||
work_path.add("campo.ini");
|
||
if (work_path.exist())
|
||
{
|
||
work_path = path;
|
||
work_path.add("campo.aut");
|
||
if (work_path.exist())
|
||
{
|
||
work_path = path;
|
||
work_path.add("ba0.exe");
|
||
if (work_path.exist())
|
||
{
|
||
work_path = path;
|
||
work_path.add("xvaga.dll");
|
||
if (work_path.exist())
|
||
ok = true; //minchia che diffidente!
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
TInstaller_mask::TInstaller_mask()
|
||
: TArray_sheet(0, 0, 0, 0, TR("Installazione"),
|
||
HR("@1|Modulo@32|Cod.@3|Versione da\ninstallare@11|Liv.\nPatch@6|Data\nRilascio@10|Versione\nInstallata@10|Liv.\nPatch@6|Data\nInstallazione@13|Aggiornamento|Patch Base"),
|
||
0x18, 4)
|
||
{
|
||
add_button(F_INSTALL, TR("Installa"), '\0', TOOL_ELABORA); // NON mettere 'I'
|
||
add_button(F_UPDATE, TR("Rileggi"), '\0', TOOL_CONVERT);
|
||
add_button(DLG_NULL, "", '\0');
|
||
add_button(DLG_INFO, TR("Info"), K_F2, TOOL_INFO);
|
||
add_button(DLG_HELP, TR("Help"), K_F1, TOOL_HELP);
|
||
xvt_toolbar_set_last_tool(toolbar(), DLG_QUIT);
|
||
|
||
_station_type = test_station_type();
|
||
_curr_mask = this;
|
||
_installed = false;
|
||
_reboot_program= NONE;
|
||
|
||
//in base al tipo di installazione che rileva decide se puo' effettuare aggiornamenti via web (un client..
|
||
//..non puo' fare aggiornamenti da web!!!)
|
||
TToken_string installada;
|
||
installada.add(TR("Installa da disco"));
|
||
installada.add(TR("Installa da web "));
|
||
TRadio_field& rf = add_radio(F_TYPE, 0, "", 1, 0, 21, "0|1", installada);
|
||
*rf.message(0, true) = "DISABLE,207|ENABLE,201";
|
||
*rf.message(1, true) = "DISABLE,201|ENABLE,207";
|
||
add_string(F_PATH, 0, "", 23, 1, 256, "B", 56).set_selector('D', EMPTY_STRING);
|
||
add_string(F_WEB, 0, "", 23, 2, 256, "", 56);
|
||
set(F_TYPE, "0", 0x1);
|
||
|
||
//deve conoscere i path adesso per poter testare se sono ok
|
||
TInstall_ini ini;
|
||
TFilename path = ini.get("DiskPath");
|
||
TFilename webpath = ini.get("WebPath");
|
||
|
||
//un client non puo' scegliere a caso da dove aggiornarsi!Solo dal suo server!
|
||
if (_station_type == 3)
|
||
{
|
||
rf.disable();
|
||
bool ko = !is_program_dir(path);
|
||
if (ko)
|
||
warning_box(TR("La cartella origine dei programmi NON <20> valida!\nSelezionarne una valida e premere 'Invio'."));
|
||
enable(F_PATH, ko);
|
||
}
|
||
|
||
add_string(F_CURPATH, 0, PR("Installa in "), 1, 3, 80, "D", 56);
|
||
|
||
set_handler(F_PATH, path_handler);
|
||
set_handler(F_WEB, web_handler);
|
||
set_handler(F_INSTALL, install_handler);
|
||
set_handler(F_UPDATE, update_handler);
|
||
set_handler(DLG_USER, tutti_handler);
|
||
|
||
|
||
//se il webpath <20> vuoto o di test, propone quello in oem.ini; non ammette che possa essere proposto un path..
|
||
//..di tipo test per impedire all'utonto di aggiornarsi da test prima di essere passato da release
|
||
if (webpath.empty() || webpath.find("test"))
|
||
{
|
||
TConfig oemini(CONFIG_OEM, "MAIN");
|
||
const int oem = oemini.get_int("OEM", NULL, -1, -1);
|
||
if (oem >= 0)
|
||
{
|
||
TString8 para; para << "OEM_" << oem;
|
||
webpath = oemini.get("Web", para);
|
||
}
|
||
}
|
||
|
||
set(F_PATH, path);
|
||
set(F_WEB, webpath);
|
||
//..fine costruzione maschera di installazione
|
||
|
||
//decide quale e' il percorso di installazione
|
||
//ha un cd o un disco di rete -> si aggiorna da questo...
|
||
if (path.exist())
|
||
autoload();
|
||
else //senno' cerca su internet se trova un path internet completo e la connessione funzionante
|
||
{
|
||
if (_station_type != 3 && webpath.full())
|
||
{
|
||
set(F_TYPE, "1", 0x1);
|
||
if (xvt_net_get_status() & 0x2) //la connessione web funziona?...
|
||
//if (yesno_box(TR("E' possibile l'aggiornamento via internet. Si desidera connettersi ora?")))
|
||
autoload(); //...quindi scarica l'elenco dei moduli da aggiornare!
|
||
}
|
||
}
|
||
|
||
DIRECTORY dir;
|
||
xvt_fsys_get_dir(&dir);
|
||
xvt_fsys_convert_dir_to_str(&dir, path.get_buffer(), path.size());
|
||
set(F_CURPATH, path);
|
||
}
|
||
|
||
TInstaller_mask::~TInstaller_mask()
|
||
{
|
||
_curr_mask = NULL;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Programma principale
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TInstaller : public TSkeleton_application
|
||
{
|
||
protected:
|
||
TInstaller_mask* _m;
|
||
|
||
protected:
|
||
virtual bool create();
|
||
virtual bool use_files() const { return false; }
|
||
virtual bool test_assistance_year() const;
|
||
virtual void main_loop();
|
||
void convert_archives();
|
||
};
|
||
|
||
|
||
bool TInstaller::test_assistance_year() const
|
||
{
|
||
// Per il momento lascia continuare: ci pensa poi la create
|
||
return true;
|
||
}
|
||
|
||
bool TInstaller::create()
|
||
{
|
||
if (!TApplication::test_assistance_year())
|
||
{
|
||
TExternal_app attivazione("ba1 -4");
|
||
attivazione.run();
|
||
dongle().login(); // Rilegge anno assistenza
|
||
}
|
||
else
|
||
update_dninst(false); // Aggiorna se necessario
|
||
|
||
//crea la maschera di installazione
|
||
_m = new TInstaller_mask();
|
||
|
||
//se e' un client
|
||
if (_m->station_type() == 3)
|
||
{
|
||
_m->disable_check();
|
||
_m->disable(F_UPDATE);
|
||
_m->disable(DLG_USER);
|
||
}
|
||
else //se e' standalone o server...
|
||
{
|
||
if (user() != ::dongle().administrator())
|
||
return error_box(TR("Solo l'utente amministratore puo' aggiornare questa postazione!"));
|
||
}
|
||
|
||
return TSkeleton_application::create();
|
||
}
|
||
|
||
void TInstaller::convert_archives()
|
||
{
|
||
bool conv = true;
|
||
if (is_power_station())
|
||
conv = yesno_box(TR("Si desidera convertire gli archivi ora?"));
|
||
if (conv)
|
||
{
|
||
_m->backup();
|
||
// Lancia conversione: ba1 -0 -C -uADMIN
|
||
TExternal_app conversion("ba1 -0 -C");
|
||
conversion.run();
|
||
}
|
||
}
|
||
|
||
void TInstaller::main_loop()
|
||
{
|
||
_m->run();
|
||
if (_m->run_conversion() && _m->station_type() < 3) // Almeno un trr installato e non e' client->conversione ammessa
|
||
{
|
||
convert_archives();
|
||
}
|
||
|
||
//controlla se ha lanciato setup.exe prima di chiudersi; se non lo ha fatto -> e' a fine installazione..
|
||
//..normale (moduli non SY) e quindi lancia ba0.exe
|
||
const bool setup_launched = _m->setup_run();
|
||
delete _m; _m = NULL;
|
||
if (!setup_launched)
|
||
{
|
||
TExternal_app ba0("ba0.exe");
|
||
ba0.run(true, true, false); // run asynchronous and not iconized!
|
||
}
|
||
}
|
||
|
||
int ba1700(int argc, char* argv[])
|
||
{
|
||
TInstaller app;
|
||
app.run(argc, argv, TR("Installazione moduli"));
|
||
return 0;
|
||
}
|