campo-sirio/setup/Setup.cpp
luca f067fe395d Patch level :
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :


git-svn-id: svn://10.65.10.50/trunk@18049 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-01-20 09:59:58 +00:00

1454 lines
54 KiB
C++
Executable File
Raw Blame History

//Il sorgente va scritto in notazione ungherese.
//Le variabili seguono la seguente regola: 'acronimo tipo'+'nome variabile cammellata'
//Es. wxArrayString 'as' + 'AcceptRefuse' -> asAcceptRefuse
#include "wxinc.h"
#ifdef WIN32
#include <shlobj.h>
#endif
#include <wx/protocol/http.h>
#include <wx/snglinst.h>
#include "key.h"
#include "wizard.h"
#include "utils.h"
///////////////////////////////////////////////////////////
// CampoFrame
///////////////////////////////////////////////////////////
class CampoFrame : public wxFrame
{
protected:
DECLARE_EVENT_TABLE();
virtual void OnErase(wxEraseEvent& e);
public:
CampoFrame();
};
BEGIN_EVENT_TABLE(CampoFrame, wxFrame)
EVT_ERASE_BACKGROUND(CampoFrame::OnErase)
END_EVENT_TABLE()
void CampoFrame::OnErase(wxEraseEvent& e)
{
//preparazione background
wxDC& dc = *e.GetDC();
const wxRect rect = GetClientSize();
wxColour c0 = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
wxColour c1 = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
wxColour c2 = wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW);
wxRect rect1 = rect; rect1.SetBottom(rect.GetBottom() / 2);
dc.GradientFillLinear(rect1, c0, c1, wxSOUTH);
wxRect rect2 = rect; rect2.SetTop(rect.GetBottom() / 2);
dc.GradientFillLinear(rect2, c1, c2, wxDOWN);
int nHeight = rect.GetHeight()/14;
wxFont* pFont = wxTheFontList->FindOrCreateFont(nHeight, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_BOLD);
dc.SetFont(*pFont);
dc.SetBackgroundMode(wxTRANSPARENT);
int w, h;
dc.GetTextExtent(RESELLER, &w, &h);
while (w > rect.width)
{
nHeight = nHeight * rect.width / w;
pFont = wxTheFontList->FindOrCreateFont(nHeight, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_BOLD);
dc.SetFont(*pFont);
dc.GetTextExtent(RESELLER, &w, &h);
}
const int k = nHeight / 16 + 1;
dc.SetTextForeground(c2);
dc.DrawText(RESELLER, rect.GetRight()-w-k/2, rect.GetHeight()-h-k/2);
dc.SetTextForeground(c1);
dc.DrawText(RESELLER, rect.GetRight()-w-k, rect.GetHeight()-h-k);
dc.SetTextForeground(c2);
dc.DrawText(PRODUCT, k, k);
dc.SetTextForeground(c1);
dc.DrawText(PRODUCT, k/2, k/2);
}
CampoFrame::CampoFrame()
: wxFrame(NULL, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0)
{
ShowFullScreen(true);
}
///////////////////////////////////////////////////////////
// CampoSetup
///////////////////////////////////////////////////////////
//classe principale, ovvero applicazione
class CampoSetup : public wxApp
{
CampoFrame* m_pMainFrame;
wxLocale m_locale;
wxString m_strSetupPath;
CampoWizard* m_pWizard;
private:
bool WriteRegistryKey(HKEY hBaseKey, const wxString strKey, const wxString& strValue) const;
wxString ReadRegistryKey(HKEY hBaseKey, const wxString strKey) const;
wxString GetFolderPath(unsigned int uPathID) const;
protected:
DECLARE_EVENT_TABLE()
//metodi principali dell'applicazione
void OnTimer(wxTimerEvent& e);
void DiskUpdate();
void InternetUpdate();
void ClientUpdate();
void NormalSetup();
bool SystemRunning(const wxString& strAppName, const wxString& strMsg) const;
bool LurchRunning() const;
bool CampoRunning() const;
//metodi di interfaccia con Windows
bool CreateIcon(unsigned int csidl, const wxFileName& strExeFile, const wxString& strLinkName) const;
void AssociateExtension(const wxFileName& strExeFile, const wxString strExt);
//...per i servers
bool CreateAutostartMode(const LurchMode iSrvAutostartMode, const wxString& strPath);
bool StopLurch() const;
bool StartLurch(const wxString& strPrgLocPath) const;
//metodi di interfaccia con il registry di Windows
wxString ReadRootRegistryKey(const wxString strKey) const;
wxString ReadLocalMachineRegistryKey(const wxString strKey) const;
bool WriteRootRegistryKey(const wxString strKey, const wxString& strValue) const;
bool WriteLocalMachineRegistryKey(const wxString strKey, const wxString& strValue) const;
//metodi di utility per i vari modi di aggiornamento
const wxString GetSourceDir(const wxString strDirName) const;
void EmptyOutDir(const wxString& strDir) const;
bool UnzipModule(const wxString& strPrgLocPath, const wxString& strSrc, const wxString& strModule) const;
void CopyDir(const wxString& strSourceDir, const wxString& strDestDir) const;
bool CopyFilesAndDirs(const wxString& FilesListI, wxString strFileCurr, const bool bIni) const;
void UpdateInstallIni(const wxString strSourcePath, const wxString strDestPath, const wxString& strModule) const;
bool HTTPGet(const wxString& strLocalPath, const wxString& strWebPath) const;
//metodi di aggiornamento non standard (client, da disco e via web con installazione moduli)
int ClientUpdateModule(const wxString& strLocalPath, const wxString& strRemotePath, const wxString strModule) const;
bool DiskUpdateModule(const wxString& strLocalPath, const wxString& strWebPath, const wxString strModule) const;
bool InternetUpdateModule(const wxString& strLocalPath, const wxString& strWebPath, const wxString strModule) const;
public:
virtual bool OnInit();
};
IMPLEMENT_APP(CampoSetup)
BEGIN_EVENT_TABLE(CampoSetup, wxApp)
EVT_TIMER(883, OnTimer)
END_EVENT_TABLE()
//----------------------------------------------------------------
// Metodi di lettura/scrittura registry di Windows (fantastici!)
//----------------------------------------------------------------
wxString CampoSetup::ReadRegistryKey(HKEY hBaseKey, const wxString strKey) const
{
wxString strValue;
HKEY hKey = NULL;
wxString strPath, strName;
wxFileName::SplitPath(strKey, &strPath, &strName, NULL);
bool ok = ::RegOpenKeyEx(hBaseKey, strPath, 0, KEY_READ, &hKey) == ERROR_SUCCESS;
if (ok)
{
BYTE buff[512];
DWORD type = REG_SZ;
DWORD dw = sizeof(buff);
ok = ::RegQueryValueEx(hKey, strName, NULL, &type, buff, &dw) == ERROR_SUCCESS;
if (ok)
strValue = buff;
::RegCloseKey(hKey);
}
return strValue;
}
wxString CampoSetup::ReadRootRegistryKey(const wxString strKey) const
{
return ReadRegistryKey(HKEY_CLASSES_ROOT, strKey);
}
wxString CampoSetup::ReadLocalMachineRegistryKey(const wxString strKey) const
{
return ReadRegistryKey(HKEY_LOCAL_MACHINE, strKey);
}
bool CampoSetup::WriteRegistryKey(HKEY hBaseKey, const wxString strKey, const wxString& strValue) const
{
HKEY hKey = NULL;
DWORD dw = 0;
//splitta la stringa in path e valore
wxString strPath, strName;
wxFileName::SplitPath(strKey, &strPath, &strName, NULL);
bool ok = ::RegCreateKeyEx(hBaseKey, strPath, 0, REG_NONE,
REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hKey, &dw) == ERROR_SUCCESS;
if (ok)
{
ok = ::RegSetValueEx(hKey, strName, 0, REG_SZ,
(BYTE*)(const wxChar*)strValue, DWORD(2*strValue.Len()+2)) == ERROR_SUCCESS;
::RegCloseKey(hKey);
}
return ok;
}
bool CampoSetup::WriteRootRegistryKey(const wxString strKey, const wxString& strValue) const
{
return WriteRegistryKey(HKEY_CLASSES_ROOT, strKey, strValue);
}
bool CampoSetup::WriteLocalMachineRegistryKey(const wxString strKey, const wxString& strValue) const
{
return WriteRegistryKey(HKEY_LOCAL_MACHINE, strKey, strValue);
}
//----------------------------------
// Metodi di interfaccia con Windows
//----------------------------------
wxString CampoSetup::GetFolderPath(unsigned int uPathID) const
{
TCHAR szPath[MAX_PATH] = wxT("");
HRESULT hres = ::SHGetFolderPath(NULL, uPathID, NULL, SHGFP_TYPE_CURRENT, szPath);
return szPath;
}
void CampoSetup::AssociateExtension(const wxFileName& strExeFile, const wxString strExt)
{
// Register icon and application
WriteRootRegistryKey(strExt, APPNAME);
wxString str = strExeFile.GetFullPath(); str += wxT(",0");
WriteRootRegistryKey(wxT("Campo\\DefaultIcon"), str);
str = strExeFile.GetFullPath(); str += wxT(" \"%1\"");
WriteRootRegistryKey(wxT("Campo\\shell\\open\\command"), str);
}
bool CampoSetup::CreateIcon(unsigned int csidl, const wxFileName& strExeFile, const wxString& strLinkName) const
{
//csidl = CSIDL_COMMON_DESKTOPDIRECTORY = desktop
//csidl = CSIDL_COMMON_STARTUP = all users esecuzione automatica
wxString strDesktopPath = GetFolderPath(csidl);
if (!strDesktopPath.IsEmpty())
{
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
IShellLink* psl;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
if (SUCCEEDED(hres))
{
// Set the path to the shortcut target and add the description.
psl->SetPath(strExeFile.GetFullPath());
psl->SetWorkingDirectory(strExeFile.GetPath());
psl->SetDescription(APPNAME);
//sceglie l'icona da quelle possibili legate al .exe in base al tipo di installazione
const InstallationType uInstallationType = m_pWizard->GetInstallationType();
//anche l'icona deve essere scelta in base al reseller
wxString strIcon = Icon();
//path completo del file icona, in modo da legarlo al link sul desktop;comincia con il path di Campo
wxString strPath = m_pWizard->GetPrgLocPath();
if (!strIcon.IsEmpty())
{
strPath += "/setup/"; //se esiste l'icona del reseller sta in setup
}
else
{
strPath += "/res/"; //se non trova l'icona del reseller prende quella standard in res
}
const int nPos = strIcon.Len()-4;
switch (uInstallationType)
{
case it_server: strIcon.insert(nPos, "Srv"); break;
case it_client: strIcon.insert(nPos, "Cln"); break;
default: break;
}
strPath << strIcon;
psl->SetIconLocation(strPath, 0);
// Query IShellLink for the IPersistFile interface for saving the
// shortcut in persistent storage.
IPersistFile* ppf;
hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (SUCCEEDED(hres))
{
wxFileName fnLnk;
wxString strName = strLinkName + ".lnk";
fnLnk.Assign(strDesktopPath, strName);
// Save the link by calling IPersistFile::Save.
wxString strPath = fnLnk.GetFullPath();
wchar_t buff[_MAX_PATH];
memset(buff, 0, sizeof(buff));
wxConvLocal.MB2WC(buff, strPath, strPath.Len());
hres = ppf->Save(buff, true);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
}
return true;
}
//-------------------------------------------
// ..per i servers di Campo
//-------------------------------------------
bool CampoSetup::StopLurch() const
{
bool ok = false;
//cerca e ferma authoriz e lurch come processi
for (int i = 0; i < 2; i++)
{
wxHTTP scServer;
if (scServer.Connect("127.0.0.1", i == 0 ? 10000 : 1883))
{
//if (scServer.BuildRequest("/stop.cgi", 0))
wxInputStream* isIs = scServer.GetInputStream("/stop.cgi");
if (isIs)
{
delete isIs;
wxSleep(3);
ok = true;
break;
}
}
}
//se lurch e' un servizio lo stoppa
const wxString strValue = ReadLocalMachineRegistryKey("SYSTEM\\CurrentControlSet\\Services\\Lurch\\Parameters\\Application");
if (!strValue.IsEmpty())
{
wxString strExecService = GetFolderPath(CSIDL_SYSTEM);
strExecService += "\\NET STOP Lurch";
wxExecute(strExecService, wxEXEC_SYNC);
}
return ok;
}
bool CampoSetup::StartLurch(const wxString& strPrgLocPath) const
{
const wxString strValue = ReadLocalMachineRegistryKey("SYSTEM\\CurrentControlSet\\Services\\Lurch\\Parameters\\Application");
if (!strValue.IsEmpty())
{
wxString strExecService = GetFolderPath(CSIDL_SYSTEM);
strExecService += "\\NET START Lurch";
wxExecute(strExecService, wxEXEC_SYNC);
}
else
{
wxString strPath = strPrgLocPath;
strPath += "/servers/lurch.exe";
wxExecute(strPath, wxEXEC_ASYNC);
}
return true;
}
bool CampoSetup::CreateAutostartMode(const LurchMode iSrvAutostartMode, const wxString& strPath)
{
//creazione dei filenames e dei path necessari in giro per la funzione
//filename (con path quindi) di Lurch.exe
wxFileName strExe(strPath, wxT("lurch.exe"));
strExe.AppendDir("servers");
//stringa path della cartella Servers in base alle scelte dell'utente
const wxString strSrvPath = strExe.GetPath();
//1) Cerca di eliminare Lurch se presente come servizio
const wxString strValue = ReadLocalMachineRegistryKey("SYSTEM\\CurrentControlSet\\Services\\Lurch\\Parameters\\Application");
if (!strValue.IsEmpty())
{
//elimina un eventuale servizio precedente (senno' col cavolo che lo riesce a modificare!)
//utilizza il programma instsrv.exe dentro la cartella servers installata
wxString strRemove = strSrvPath + "\\instsrv Lurch REMOVE";
const long lRemove = wxExecute(strRemove, wxEXEC_SYNC);
}
//2) Cerca di fermare Lurch se presente come programma in esecuzione automatica
else
{
if (LurchRunning())
StopLurch();
}
switch (iSrvAutostartMode)
{
//esecuzione server come servizi (magia!)
case lm_service:
{
//aggiunge la voce ai servizi di windows (dentro strumenti di amministrazione)
//utilizza i programmi instrv.exe e srvany.exe dentro la cartella servers installata
wxString strCreateService = strSrvPath + "\\instsrv Lurch ";
strCreateService += strSrvPath;
strCreateService += "\\srvany.exe";
//esegue il programma di installazione servizi di Windows creando la voce
const long lExec = wxExecute(strCreateService, wxEXEC_SYNC);
if (lExec >= 0)
{
//crea le voci nel registry di windows
WriteLocalMachineRegistryKey("SYSTEM\\CurrentControlSet\\Services\\Lurch\\Parameters\\Application", strExe.GetFullPath());
wxString strExecService = GetFolderPath(CSIDL_SYSTEM);
strExecService += "\\NET START Lurch";
//avvia il servizio
const long lExecLurch = wxExecute(strExecService, wxEXEC_SYNC);
if (lExecLurch < 0)
WarningBox("Impossibile eseguire il servizio del gestore applicazioni.\nLanciarlo manualmente dagli strumenti di amministrazione nel pannello di controllo!");
}
else
WarningBox("Impossibile registrare il servizio per l'esecuzione automatica del gestore applicazioni.\nSelezionare una diversa modalita' di esecuzione!");
}
break;
//link nella cartella esecuzione automatica
case lm_autostart:
{
CreateIcon(CSIDL_COMMON_STARTUP, strExe, "lurch");
}
break;
default:
break;
}
return true;
}
//----------------------------------------------------------------
// Metodi di utility per i vari tipi di aggiornamento
//----------------------------------------------------------------
static int PatchCompare(const wxString& first, const wxString& second)
{
const wxFileName fn1(first);
const wxFileName fn2(second);
const wxString strName1 = fn1.GetName().Lower();
const wxString strName2 = fn2.GetName().Lower();
if (strName1 == "syinst1")
return -1;
if (strName2 == "syinst1")
return 1;
return strName1.CompareTo(strName2);
}
const wxString CampoSetup::GetSourceDir(const wxString strDirName) const
{
wxFileName strSourcePath(m_strSetupPath, "pippo.txt");
strSourcePath.AppendDir("..");
strSourcePath.AppendDir("..");
strSourcePath.AppendDir(strDirName);
strSourcePath.MakeAbsolute();
const wxString strSrc = strSourcePath.GetPath();
return strSrc;
}
//metodo per aggiornare il modulo SY in install.ini
void CampoSetup::UpdateInstallIni(const wxString strSourcePath, const wxString strDestPath, const wxString& strModule) const
{
for (int j = 0; j < 2; j++)
{
wxString strParagraph = strModule;
if (j > 0)
strParagraph << j;
CampoIniFile InstallIniSource(strSourcePath, strParagraph);
CampoIniFile InstallIniDest(strDestPath, strParagraph);
wxString strWrk;
long nIndex;
for (bool ok = InstallIniSource.GetFirstEntry(strWrk, nIndex); ok; ok = InstallIniSource.GetNextEntry(strWrk, nIndex))
{
InstallIniDest.Set(strWrk, InstallIniSource.Get(strWrk));
}
}
}
bool CampoSetup::UnzipModule(const wxString& strPrgLocPath, const wxString& strSrc, const wxString& strModule) const
{
//Attenzione! Se c'e' il server di chiavi in funzione va fermato prima di procedere!!!!
const bool bLurch = strModule == "sr" && LurchRunning();
if (bLurch)
StopLurch();
bool ok = false;
wxArrayString asFilesList;
size_t uFilesToCopy;
//..contando anche quanti sono e memorizzandoli in un array asFileList
if(wxDir::Exists(strSrc))
{
uFilesToCopy = wxDir::GetAllFiles(strSrc, &asFilesList, strModule+"*.zip");
if (uFilesToCopy > 0)
{
//ordina le patch per numero crescente ma mette davanti a tutte il pacco (sysinst1)
asFilesList.Sort(PatchCompare);
for (size_t i = 0; i < uFilesToCopy; i++)
{
UnzipFile(asFilesList[i] , strPrgLocPath);
}
//aggiorna l'install.ini in base al numero di patch e versione dell'ultimo file zip di sistema
//ci vuole un giro allucinogeno per trasformare il .zip in .ini e togliere quel cazzo di 1 in fondo
wxFileName strLastFile(asFilesList[uFilesToCopy - 1]); //zip con path completo
wxString strWrk = strLastFile.GetName();
strWrk.Truncate(strWrk.Len() - 1);
strLastFile.SetName(strWrk);
strLastFile.SetExt("ini");
strWrk = strLastFile.GetFullPath();
//adesso che ha trovato quello sporco ultimo .ini prende versione e patch e le copia nell'install.ini..
//..nella dir dei programmi; lo fa paragrafo x paragrafo ([sy],[sy1]..)
//potrebbe sembrare assurdo un for, ma e' per futuri sottomoduli con numero > 1
UpdateInstallIni(strWrk, strPrgLocPath + "/install.ini", strModule);
}
}
//Adesso puo' far ripartire il server di chiavi
if (bLurch)
StartLurch(strPrgLocPath);
return uFilesToCopy > 0;
}
bool CampoSetup::CopyFilesAndDirs(const wxString& FilesListI, wxString strFileCurr, const bool bIni) const
{
bool ok = true;
//i files .ini vanno trattati con i guanti (se esistono gia' non vanno copiati!!!)
//parte da eseguire solo in caso sia indicata la trattazione degli ini (bIni true)
if (bIni)
{
strFileCurr.MakeLower(); //minuscolizzazione di sicurezza
const wxFileName strFileName(strFileCurr);
if (strFileName.GetExt() == "ini")
{
const wxString strName = strFileName.GetName();
//campo.ini e install.ini vanno lasciati stare se esistono (aggiornamento)!!!
if ((strName == "campo" || strName == "install") && strFileName.FileExists())
ok = false;
}
}
if (ok)
ok = CopiaFile(FilesListI, strFileCurr);
return ok;
}
//metodo per copiare una directory e tutti i files che contiene
void CampoSetup::CopyDir(const wxString& strSourceDir, const wxString& strDestDir) const
{
if (wxDir::Exists(strSourceDir))
{
wxArrayString asFilesList;
const size_t uFilesToCopy = wxDir::GetAllFiles(strSourceDir, &asFilesList, "*.*");
const size_t uFrom = strSourceDir.Len();
for (size_t i = 0; i < uFilesToCopy; i++)
{
wxString strFileDest = strDestDir + asFilesList[i].Mid(uFrom);
CopiaFile(asFilesList[i], strFileDest);
}
}
}
//metodo per accoppare tutti i files di una directory
void CampoSetup::EmptyOutDir(const wxString& strDir) const
{
if (wxFileName::DirExists(strDir))
{
wxArrayString asFilesList;
const size_t uFilesToKill = wxDir::GetAllFiles(strDir, &asFilesList, "*.*");
for (size_t i = 0; i < uFilesToKill; i++)
::wxRemoveFile(asFilesList[i]);
}
}
//-----------------------------------------------------
// METODI BASSO LIVELLO PER AGGIORNAMENTI NON STANDARD
//-----------------------------------------------------
//----------------------------
// 1) AGGIORNAMENTO CLIENT
//----------------------------
//Aggiornatore client. Copia i files del programma da una directory remota su un server campo nella directory...
//...locale di campo
int CampoSetup::ClientUpdateModule(const wxString& strLocalPath, const wxString& strRemotePath, const wxString strModule) const
{
int nLocVer, nLocPatch, nRemVer, nRemPatch;
{
CampoIniFile iniLocalInstall(strLocalPath + "/install.ini", strModule);
nLocVer = iniLocalInstall.GetInt("Versione");
nLocPatch = iniLocalInstall.GetInt("Patch");
CampoIniFile iniRemoteInstall(strRemotePath + "/install.ini", strModule);
nRemVer = iniRemoteInstall.GetInt("Versione");
nRemPatch = iniRemoteInstall.GetInt("Patch");
}
int cmp = nLocVer - nRemVer;
if (cmp == 0)
cmp = nLocPatch - nRemPatch;
//il client e' piu' indietro e quindi va aggiornato!
if (cmp < 0)
{
bool bOk = true;
CampoProgressDialog pi("Aggiornamento elenco files dal server...", 100, m_pWizard);
wxArrayString asGroups;
{
wxString strGroup;
long nIndex;
CampoIniFile iniRemoteInstall(strRemotePath + "/install.ini", "");
for (bool ok = iniRemoteInstall.GetFirstGroup(strGroup, nIndex); ok; ok = iniRemoteInstall.GetNextGroup(strGroup, nIndex))
{
if(strGroup.Len() > 2 && strGroup.StartsWith(strModule))
asGroups.Add(strGroup);
}
}
//controlla tutti i sottomoduli del modulo [sy1],[sy2]...
for (size_t i = 0; i < asGroups.GetCount() && bOk; i++)
{
const wxString& strParagraph = asGroups[i];
CampoIniFile iniRemoteInstallModule(strRemotePath + "/install.ini", strParagraph);
//install.ini locale che deve essere aggiornato durante la copia dei files!
CampoIniFile iniLocalInstall(strLocalPath + "/install.ini", strParagraph);
//ogni file dell'elenco del sottomodulo corrente va copiato
for (int j = 0;; j++)
{
pi.Pulse(); //magica barra modello supercar!
const wxString strVarName = wxString::Format("File(%d)", j);
wxString strCurrFile = iniRemoteInstallModule.Get(strVarName);
if (strCurrFile.IsEmpty())
break;
strCurrFile = strCurrFile.BeforeFirst('|');
const wxString strSrcPath = strRemotePath + "/" + strCurrFile;
const wxString strDstPath = strLocalPath + "/" + strCurrFile;
//copia il file remoto di origine sul file locale di destinazione (overwrite=true di default)
if (!CopiaFile(strSrcPath, strDstPath))
{
wxString strError;
strError += "\nAssicurarsi che il client locale di ";
strError += APPNAME;
strError += " non sia in funzione.\n";
strError += "Assicurarsi che il server di ";
strError += APPNAME;
strError += " sia in funzione e raggiungibile in rete.\n";
strError += "Aggiornamento interrotto!";
ErrorBox(strError);
bOk = false;
break;
}
//se ci sono zip deve scompattarli (per ora esiste solo res.zip)
if (strCurrFile.EndsWith("res.zip"))
{
UnzipFile(strDstPath, strLocalPath + "/res");
}
//se riesce la copia del file aggiorna l'install.ini sul file (se non lo facesse non comparirebbero...
//...eventuali nuovi files
iniLocalInstall.Set(strVarName, strCurrFile);
} //for(int j...
//una volta termiata la copia dei files del sottmodulo[i] scatta l'aggiornamento dell'install.ini locale...
//...al livello versione/patch appena copiate sempre del sottomodulo[i]
iniLocalInstall.Set("Versione", nRemVer);
iniLocalInstall.Set("Patch", nRemPatch);
} //for(int i...
//una volta termiata la copia dei files dell'intero modulo scatta l'aggiornamento dell'install.ini locale al..
//..livello versione/patch appena copiate
CampoIniFile iniLocalInstall(strLocalPath + "/install.ini", strModule);
iniLocalInstall.Set("Versione", nRemVer);
iniLocalInstall.Set("Patch", nRemPatch);
} //if(cmp<0...
return cmp;
}
//----------------------------
// 2) AGGIORNAMENTO DA DISCO
//----------------------------
//Aggiornatore da disco. Copia i files delle patch da una directory su disco in una directory di appoggio...
//...temporanea dove esegue lo scompattamento con destinazione la directory locale
bool CampoSetup::DiskUpdateModule(const wxString& strLocalPath, const wxString& strDiskPath, const wxString strModule) const
{
//puo' chiamare direttamente il metodo che scompatta tutte le patch del modulo a partire dal pacco iniziale...
//...fino all'ultima;il metodo le ordina gia' in modo crescente di numero d'ordine
return UnzipModule(strLocalPath, strDiskPath, strModule);
}
//-------------------------------
// 3) AGGIORNAMENTO DA INTERNET
//-------------------------------
bool CampoSetup::HTTPGet(const wxString& strLocalPath, const wxString& strWebPath) const
{
wxString strServer, strPath;
int nSlash = strWebPath.First('/');
strServer = strWebPath.Left(nSlash);
strPath = strWebPath.Mid(nSlash);
wxHTTP http;
//connessione al server web con le patch
if (http.Connect(strServer))
{
wxInputStream* pStream = http.GetInputStream(strPath);
if (pStream != NULL)
{
//compila un file di testo temporaneo con l'elenco dei files che trova sul server
wxFileOutputStream fos(strLocalPath);
fos.Write(*pStream);
delete pStream;
return true;
}
}
return false;
}
//Aggiornatore via web. Copia i files delle patch da una directory web remota in una directory di appoggio...
//...temporanea dove esegue lo scompattamento con destinazione la directory locale
bool CampoSetup::InternetUpdateModule(const wxString& strLocalPath, const wxString& strWebPath, const wxString strModule) const
{
bool ok = false;
int nLocVer, nLocPatch;
{
CampoIniFile iniLocalInstall(strLocalPath + "/install.ini", strModule);
nLocVer = iniLocalInstall.GetInt("Versione");
nLocPatch = iniLocalInstall.GetInt("Patch");
}
//Svuota,elimina e ricrea una directory temporanea di appoggio ove mettere i files delle patch da scompattare
//E' necessaria questa operazione per non trovarsi ancora files di vecchie patch parcheggiati nella dir!
const wxString strTempDir = wxFileName::GetTempDir() + "/setup/";
if (wxDir::Exists(strTempDir))
{
EmptyOutDir(strTempDir); //deve svuotare la directory dai files per poterla eliminare!!!
::wxRmdir(strTempDir); //elimina la dir adesso vuota
}
CheckAndMakeDir(strTempDir, wxEmptyString); //la ricrea con i permessi dell'utente windows corrente!!
const wxString strTempFile = strTempDir + "httpdir.txt";
if (HTTPGet(strTempFile, strWebPath))
{
//partendo dal file temporaneo ne compila un secondo con i soli nomi dei file validi da scaricare
//i criteri di selezione sono il nome del modulo ed il livello patch
wxTextFile tfFilesList;
if (tfFilesList.Open((strTempFile)))
{
CampoProgressDialog pi("Aggiornamento elenco files dal server...", (int)tfFilesList.GetLineCount(), m_pWizard);
for (wxString strWrk = tfFilesList.GetFirstLine(); !tfFilesList.Eof(); strWrk = tfFilesList.GetNextLine())
{
int nPos = strWrk.Find("href");
if (nPos > 0)
{
wxString strHref = strWrk.Mid(nPos + 5, 16);
strHref = strHref.AfterFirst('"');
strHref = strHref.BeforeLast('"');
if (!pi.Update((int)tfFilesList.GetCurrentLine(), strHref))
break;
//lavora solo con i files del modulo in questione
if (strHref.StartsWith(strModule))
{
const wxString strPatch = strHref.Mid(2, 4).Lower();
const wxString strExt = strHref.Right(4).Lower();
// 1) e' un pacco
//se e' un pacco devo sapere se e' piu' recente della installazione corrente (potrebbe essere un pacco nuovo..
//..ricompattato) oppure se e' piu' vecchio e non va toccato (e' ad esempio il pacco originale)
if (strPatch == "inst")
{
if (strExt == ".ini") //operazioni sull'ini x sapere versione e patch
{
HTTPGet(strTempDir+strHref, strWebPath+strHref);
CampoIniFile iniInst(strTempDir+strHref, strModule);
const int nRemoteVer = iniInst.GetInt("Versione");
const int nRemotePatch = iniInst.GetInt("Patch");
//se deve aggiornarsi con il pacco scarica pure lo zip cosi' e' a posto
if ((nRemoteVer > nLocVer) || ((nRemoteVer == nLocVer) && (nRemotePatch > nLocPatch)))
{
const int nDot = strHref.Find('.', true);
strHref = strHref.Left(nDot) + "1.zip";
HTTPGet(strTempDir+strHref, strWebPath+strHref);
}
else //se non deve aggiornarsi elimina l'ini in modo da non avere una mezza patch che farebbe incazzare l'unzipper
wxRemoveFile(strTempDir+strHref);
} //if(strHref.EndsWith("ini")...
} //if(strPatch == "inst")...
// 2) e' una patch
else //se invece e' una normale patch... else di if(strPatch=="inst"..
{
//controlla che sia pi<70> avanti del suo livello patch e che sia un file utile (servono solo .ini e .zip)
if (atoi(strPatch) > nLocPatch && (strExt==".ini" || strExt==".zip"))
HTTPGet(strTempDir+strHref, strWebPath+strHref);
}
} //if(strHref.StartsWith(strModule))...
} //if(nPos>0)...
} //for(wxString strWrk = tf...
//chiude il file temporaneo
tfFilesList.Close();
} //if(tfFilesList...
//scompatta le patch di sistema e aggiorna l'install.ini locale
ok = UnzipModule(strLocalPath, strTempDir, strModule);
} //if(HTTPGet(...
return ok;
}
//-----------------------------------------------------
// METODI ALTO LIVELLO PER AGGIORNAMENTI NON STANDARD
//-----------------------------------------------------
//---------------------------------------------------------------
// 1) metodo per l'aggiornamento dei client di rete in automatico
//---------------------------------------------------------------
void CampoSetup::ClientUpdate()
{
wxFileName fn(m_strSetupPath);
fn.AppendDir("..");
fn.MakeAbsolute();
fn.SetFullName("install.ini");
const wxString strLocalPath = fn.GetPath();
wxString strRemotePath;
{
CampoIniFile iniLocalInstall(fn.GetFullPath(), "Main");
strRemotePath = iniLocalInstall.Get("DiskPath");
}
ClientUpdateModule(strLocalPath, strRemotePath, "sy");
wxSetWorkingDirectory(strLocalPath);
wxExecute("ba1 -6 /uADMIN");
}
//-----------------------------------------------------------------------------------------------
// 2) metodo per l'aggiornamento da disco attraverso il menu di Manutenzione/Installazione moduli
//-----------------------------------------------------------------------------------------------
void CampoSetup::DiskUpdate()
{
wxFileName fn(m_strSetupPath);
fn.AppendDir("..");
fn.MakeAbsolute();
fn.SetFullName("install.ini");
const wxString strLocalPath = fn.GetPath();
wxString strRemotePath;
{
CampoIniFile iniLocalInstall(fn.GetFullPath(), "Main");
strRemotePath = iniLocalInstall.Get("DiskPath");
}
DiskUpdateModule(strLocalPath, strRemotePath, "sy");
DiskUpdateModule(strLocalPath, strRemotePath, "sr");
wxSetWorkingDirectory(strLocalPath);
wxExecute("ba1 -6 /uADMIN");
}
//----------------------------------------------------------------------------------------
// 3) metodo per l'aggiornamento via internet attraverso Manutenzione/Installazione moduli
//----------------------------------------------------------------------------------------
void CampoSetup::InternetUpdate()
{
//install.ini locale dove setup.exe e' in esecuzione
wxFileName fn(m_strSetupPath);
fn.AppendDir("..");
fn.MakeAbsolute();
fn.SetFullName("install.ini");
const wxString strLocalPath = fn.GetPath();
//quale e' il path web da cui aggiornarmi?
wxString strRemotePath;
{
//Install.ini locale da cui leggere il path di dove sta il mio server web
CampoIniFile iniLocalInstall(fn.GetFullPath(), "Main");
strRemotePath = iniLocalInstall.Get("WebPath");
}
//aggiornamento dei moduli SY e SR via web
InternetUpdateModule(strLocalPath, strRemotePath, "sy");
InternetUpdateModule(strLocalPath, strRemotePath, "sr");
//lanciare ba1.exe -6 in uscita
wxSetWorkingDirectory(strLocalPath);
wxExecute("ba1 -6 /uADMIN");
}
//--------------------------------------------------------------------------
//metodo per tutte le installazioni e gli aggiornamenti automatici in locale
//--------------------------------------------------------------------------
void CampoSetup::NormalSetup()
{
//creazione del CampoWizard, ovvero dell'insieme di finestre per gestire installazione/aggiornamento
m_pWizard = new CampoWizard(m_pMainFrame);
if (m_pWizard->Run())
{
//e' una DEMO o una versione normale?
const bool bInstallDemoVersion = m_pWizard->GetInstDemoVersion();
// 0) INSTALLAZIONE VERSIONE DEMO (SIETE PAZZI?)
//----------------------------------------------
if (bInstallDemoVersion)
{
const wxString& strPrgLocPath = "c:/campodemo";
const wxString& strDataPath = strPrgLocPath + "/dati";
const wxString& strHelpPath = strPrgLocPath + "/htmlhelp";
//creazione delle directories necessarie alla installazione DEMO
CheckAndMakeDir(strPrgLocPath, "programmi");
CheckAndMakeDir(strDataPath, "dati");
CheckAndMakeDir(strHelpPath, "help");
//copia della campodemo sull'hard disk in c:\campodemo
wxArrayString asDemoList;
const wxString strSrc = GetSourceDir("campodemo");
if (wxDir::Exists(strSrc))
{
const size_t uFilesToCopy = wxDir::GetAllFiles(strSrc, &asDemoList);
wxString strFileCurr;
const size_t nPathLenght = strSrc.Len();
CampoProgressDialog pi("Installazione Versione Demo...", (int)uFilesToCopy, m_pWizard);
for (size_t i = 0; i < uFilesToCopy; i++)
{
if (!pi.Update((int)i, asDemoList[i]))
break;
asDemoList[i].Lower();
strFileCurr = strPrgLocPath;
strFileCurr += asDemoList[i].Mid(nPathLenght);
if (!strFileCurr.IsEmpty())
{
if (!CopyFilesAndDirs(asDemoList[i], strFileCurr, false))
break;
}
}
//icona sul desktop
const bool bDesktopShortcut = m_pWizard->GetDesktopShortcut();
if (bDesktopShortcut)
{
const wxFileName strExe("c:/campodemo", wxT("ba0.exe"));
CreateIcon(CSIDL_COMMON_DESKTOPDIRECTORY, strExe, "CampoDEMO");
}
//lanciare ba0.exe in uscita
wxSetWorkingDirectory(strPrgLocPath);
wxExecute("ba0");
}
}
else //tutti i casi normali (std,server,client,aggiornamento)
{
// 1) RACCOLTA PARAMETRI GENERALI INSTALLAZIONE (tipo,path,cartelle,servers,...)
//------------------------------------------------------------------------------
//tipo di installazione/aggiornamento
const InstallationType uInstallationType = m_pWizard->GetInstallationType();
const bool bNewInstallation = uInstallationType != it_upgrade;
//installazione servers? solo per server di campo
const bool bInstallLurch = uInstallationType == it_server && (m_pWizard->GetInstUseAuth() || m_pWizard->GetInstUseDict());
//uso servers? sarebbe solo per i client ma lo teniamo buono per tutti
const bool bUseLurch = uInstallationType != it_server && (!m_pWizard->GetSrvAuth().IsEmpty() || !m_pWizard->GetSrvDict().IsEmpty());
//installazione datidemo? (oddio speriamo di no!; comunque vale solo per installazione standard)
const bool bInstallDemoData = uInstallationType == it_standalone && m_pWizard->GetInstDemoData();
//cartelle selezionate dall'utente
const wxString& strPrgLocPath = m_pWizard->GetPrgLocPath();
const wxString& strDataPath = m_pWizard->GetDataPath();
//se nuova installazione deve anche creare la directory di destinazione
if (bNewInstallation)
{
//creazione della directory dei programmi (compreso l'intero albero directory)
CheckAndMakeDir(strPrgLocPath, "programmi");
//creazione della directory dei dati (compreso l'intero albero directory)
//un client NON installa i dati!! (senno' e' una installazione locale semplice)
if (uInstallationType != it_client)
CheckAndMakeDir(strDataPath, "dati");
}
// 2) COPIA DEI FILES DI INSTALLAZIONE DALLA CARTELLA CAMPO (E SUBDIRS) (SU CD) ALLA CARTELLA DESTINAZIONE
//--------------------------------------------------------------------------------------------------------
//copia del contenuto della cartella campo nella cartella di destinazione (installaz/aggiornam)
//per prima cosa cerca la cartella dei files sorgente...
wxArrayString asFilesList;
wxFileName strSourcePath(m_strSetupPath, "*.*");
strSourcePath.AppendDir("..");
strSourcePath.AppendDir("..");
strSourcePath.AppendDir("campo");
strSourcePath.MakeAbsolute();
//stringa inutile al programma ma decisiva per il programmatore
const wxString strSrc = strSourcePath.GetPath();
//..contando anche quanti sono e memorizzandoli in un array asFileList
const size_t uFilesToCopy = wxDir::GetAllFiles(strSrc, &asFilesList);
const size_t nPathLenght = strSrc.Len();
//progress bar
CampoProgressDialog pi("Installazione Dati e Programmi di base...", (int)uFilesToCopy, m_pWizard);
for (size_t i = 0; i < uFilesToCopy; i++)
{
//per ogni file da copiare controlla i path sorgente e destinazione(problema con sottodirectory tipo..
//..dati); strFileCurr va lasciato qui perche' DEVE ESSERE AZZERATO ad ogni cambio file!!!!!!
wxString strFileCurr;
//controlla se il file corrente e' dentro una sottodirectory (tipo dati,servers,setup...) oppure e' al..
//..primo livello (quindi e' un file di programma)
wxString strSourceFile = asFilesList[i].Lower();
strSourceFile.Replace("\\", "/");
//e' in una subdir se la lunghezza del suo path prima dell'ultimo '/' e' > della lunghezza del path di root
const bool bIsSubDir = strSourceFile.Find('/', true) > (int)nPathLenght;
//2A) files con subdirectory
if (bIsSubDir)
{
//files dei dati standard! solo in caso di nuova installazione!!
if (strSourceFile.Find("/dati/") > 0)
{
//i DATI NON VANNO MAI installati in caso di aggiornamento!!!
//i DATI NON VANNO MAI installati in caso di installazione client!!!
//e nemmeno in caso si scelga di installare i dati demo (senno' sporca la dir dati e i datidemo non si installano)
//Ricordare che c'e' gia' stato il controllo nella Forward della pagina di selezione, quindi la cartella..
//..di destinazione e' comunque vuota
if (bNewInstallation && uInstallationType != it_client && !bInstallDemoData)
{
strFileCurr = strDataPath;
strFileCurr += asFilesList[i].Mid(nPathLenght + 5);
//Ulteriore controllo di sicurezza: se trova il file di destinazione gia' presente..
//..NON lo sovrascrive (lo mette vuoto cosi' non lo copia)
if (wxFileName::FileExists(strFileCurr))
strFileCurr = "";
}
} else
if (strSourceFile.Find("/servers/") > 0) //che fare con i servers? copiare la directory...
{
if (bInstallLurch) //..ma solo se devi installare i servers
{
strFileCurr = strPrgLocPath;
strFileCurr += "/servers";
strFileCurr += asFilesList[i].Mid(nPathLenght + 8);
}
}
else //files vari di altre subdirectory che si installano sempre (es. setup)
{
strFileCurr = strPrgLocPath;
strFileCurr += asFilesList[i].Mid(nPathLenght);
}
}
//2B) files senza subdirectory (programmi!)
else
{
strFileCurr = strPrgLocPath;
strFileCurr += asFilesList[i].Mid(nPathLenght);
}
//copia i files nella cartella di destinazione (programmi,dati,cazzi e mazzi);se il nome del file..
//..di destinazione e' vuoto significa che non lo deve copiare!! (es. dati in aggiornamento)
if (!strFileCurr.IsEmpty())
{
//aggiorna la progind
if (!pi.Update((int)i, asFilesList[i]))
break;
//eventuali sottodirectory le crea (solo se hanno un nome) e poi copia fisicamente i files
//se un file non si copia interrompe l'installazione con un ErrorBox
if (!CopyFilesAndDirs(asFilesList[i], strFileCurr, true))
break;
} //if (!strFileCurr.IsEmpty()..
} //for(size_t...
UpdateInstallIni(strSrc + "/install.ini", strPrgLocPath + "/install.ini", "sy");
// 3) INSTALLAZIONE DATI DEMO
//---------------------------
//installazione dei dati dimostrativi (che schifo!).Non si puo' fare in aggiornamento!
/* if (bInstallDemoData && uInstallationType < 3)
{
//trova la cartella datidemo da copiare
wxArrayString asDataList;
const wxString strSrc = GetSourceDir("datidemo");
//conta i files da copiare e si lancia nell'operazione di copiatura...
//Vale quanto detto per l'installazione dell'area dati
const size_t uFilesToCopy = wxDir::GetAllFiles(strSrc, &asDataList);
wxString strFileCurr;
const size_t nPathLenght = strSrc.Len();
CampoProgressDialog pi("Installazione Dati Demo...", (int)uFilesToCopy, m_pWizard);
for (size_t i = 0; i < uFilesToCopy; i++)
{
if (!pi.Update((int)i, asDataList[i]))
break;
asDataList[i].Lower();
strFileCurr = strDataPath;
strFileCurr += asDataList[i].Mid(nPathLenght);
if (!strFileCurr.IsEmpty())
{
//eventuali sottodirectory le crea (solo se hanno un nome) e poi copia fisicamente i files
//se un file non si copia interrompe l'installazione con un ErrorBox
if (!CopyFilesAndDirs(asDataList[i], strFileCurr, false))
break;
} //if (!strFileCurr.IsEmpty()..
} //for (size_t i = 0...
} //if(bInstallDemoData... */
// 4) COMPILAZIONE CAMPO.INI CON CONFIGURAZIONE NUOVA INSTALLAZIONE
//-----------------------------------------------------------------
//adesso deve compilare il campo.ini se nuova installazione..
if (bNewInstallation)
{
{ //parentesi necessaria per la scrittura immediata (non cancellare! serve per debug)
//paragrafo [Main]
CampoIniFile CampoIniMain(strPrgLocPath + "/campo.ini", "Main");
const unsigned int uDongleType = m_pWizard->GetDongleType();
CampoIniMain.Set("Donglehw", uDongleType);
CampoIniMain.Set("Study", strDataPath);
CampoIniMain.Set("Firm", "com");
//server,client o standalone?
CampoIniMain.Set("Type", uInstallationType);
}
//paragrafo [Server]
if (bInstallLurch || bUseLurch)
{
CampoIniFile CampoIniSrv(strPrgLocPath + "/campo.ini", "Server");
CampoIniSrv.Set("Dongle", m_pWizard->GetSrvAuth());
CampoIniSrv.Set("Dictionary", m_pWizard->GetSrvDict());
}
} //if(bNewInstallation...
else //e' un aggiornamento! scrive il type
{
CampoIniFile CampoIniMain(strPrgLocPath + "/campo.ini", "Main");
//SOLO se sta aggiornando una versione antecedente alla 10.0 scrive la variabile Type nel campo.ini..
//..ovvero deve testare se Type = 0
if (CampoIniMain.GetInt("Type") == 0)
CampoIniMain.Set("Type", CampoIniMain.GetInstallationType());
}
// 5) COMPILAZIONE\AGGIORNAMENTO INSTALL.INI CON DISKPATH
//-------------------------------------------------------
//..e modificare comunque l'install.ini aggiornando eventualmente l'origine dei programmi
//parentesi necessaria per la scrittura immediata (non cancellare! serve per debug)
{
CampoIniFile CampoInstall(strPrgLocPath + "/install.ini", "Main");
if (uInstallationType == it_client) //client: directory origine sul server
CampoInstall.Set("DiskPath", m_pWizard->GetPrgNetPath());
else //e' il path assoluto dell'install.ini che sta in 'program' (es. D:\program)
{
const wxString strSrc = GetSourceDir("program");
CampoInstall.Set("DiskPath", strSrc);
}
}
// 6) AGGIORNAMENTO DI ADMIN.INI CON IL TEMA DEL RESELLER
//---------------------------------------------------------
//carica il tema predefinito del reseller dentro l'admin.ini che sta in cartella programmi\dati\config..
//..in modo da vederli subito quando lancer<65> ba1 (e successivamente ba0)
if (bNewInstallation)
{
//file sorgente
const wxString strThemeFileName = Theme();
wxString strSrcThemePath = m_strSetupPath;
strSrcThemePath << strThemeFileName;
CampoIniFile CampoTheme(strSrcThemePath, "Standard");
//file di destinazione
CampoIniFile CampoDestAdmin(strDataPath + "/config/admin.ini", "Colors");
//copia del tema standard nell'admin.ini di destinazione
long nIndex;
wxString strKey;
//ciclo su tutte le variabili del paragrafo di origine
for (bool ok = CampoTheme.GetFirstEntry(strKey, nIndex); ok; ok = CampoTheme.GetNextEntry(strKey, nIndex))
{
//copia nel corrispondente paragrafo di destinazione
CampoDestAdmin.Set(strKey, CampoTheme.Get(strKey));
}
}
// 7) AGGIORNAMENTO DEL MODULO SY CON EVENTUALI PATCH PRESENTI IN PROGRAM DEL CD E AGGIORNAMENTO INSTALL.INI
//----------------------------------------------------------------------------------------------------------
//procede poi al caricamento delle patch eventuali di sistema all'interno della dir 'program' e al..
//..conseguente riaggiornamento del livello versione/patch di SY ed SR in install.ini
const wxString strPrgCDPath = GetSourceDir("program");
if (wxFileName::DirExists(strPrgCDPath))
{
const wxString strSetupCDPath = strPrgCDPath + "/setup";
const wxString strSetupLocPath = strPrgLocPath + "/setup";
CopyDir(strSetupCDPath, strSetupLocPath);
UnzipModule(strPrgLocPath, strPrgCDPath, "sy");
UnzipModule(strPrgLocPath, strPrgCDPath, "sr");
}
// 8) CREAZIONE AUTOSTART DEI SERVERS (SE CI SONO)
//------------------------------------------------
//solo se sta installando campo in postazione server e deve installare un gestore di servizi..
//..avvia la procedura della creazione dell'autostart(un casino). Questa procedura non puo'..
//..valere per l'aggiornamento, che agisce in modo diverso
if (bNewInstallation)
{
const LurchMode iSrvAutostartMode = m_pWizard->GetSrvAutostartMode();
if (iSrvAutostartMode != lm_none)
{
CreateAutostartMode(iSrvAutostartMode, strPrgLocPath);
}
}
// 9) CREAZIONE DELL'ICONA SUL DESKTOP
//------------------------------------
const bool bDesktopShortcut = m_pWizard->GetDesktopShortcut();
if (bDesktopShortcut)
{
const wxFileName strExe(strPrgLocPath, wxT("ba0.exe"));
wxString strLnk;
CampoIniFile CampoIniMain(strPrgLocPath + "/campo.ini", "Main");
InstallationType nInstType = CampoIniMain.GetInstallationType();
switch (nInstType)
{
case it_server:
strLnk = "Campo Enterprise (Server)";
break;
case it_client:
strLnk = "Campo Enterprise (Client)";
break;
default:
strLnk = "Campo Enterprise";
break;
}
//crea comunque l'icona
CreateIcon(CSIDL_COMMON_DESKTOPDIRECTORY, strExe, strLnk);
}
// 10) AGGIORNAMENTO CAMPO.STP
//---------------------------
if (bNewInstallation)
{
//deve aggiungere la nuova installazione al campo.stp
for (int i = 1;; i++)
{
wxString strGroup;
strGroup << i;
CampoIniFile CampoStp("C:\\campo.stp", strGroup);
wxString strPath = CampoStp.Get("Program");
if (strPath.IsEmpty())
{
CampoStp.Set("Program", strPrgLocPath);
break;
}
}
}
// 11) CHIUDE IL SETUP LANCIANDO BA1 -6 PER INSTALLAZIONE MODULI
//-------------------------------------------------------------
//lanciare ba1.exe -6 in uscita
if (wxSetWorkingDirectory(strPrgLocPath))
wxExecute("ba1 -6 /uADMIN");
else
ErrorBox("Impossibile installare i moduli. Cartella di destinazione irraggiungibile!");
}
} //if (m_pWizard->Run())...
m_pWizard->Destroy();
}
//------------------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////////
// Metodi per il controllo preventivo di eventuali cazzate in procinto di accadere
////////////////////////////////////////////////////////////////////////////////////
bool CampoSetup::SystemRunning(const wxString& strAppName, const wxString& strMsg) const
{
wxSingleInstanceChecker sicProgram(strAppName);
int i;
for (i = 10; i > 0 && sicProgram.IsAnotherRunning(); i--)
wxSleep(1);
if (i <= 0 && !strMsg.IsEmpty())
ErrorBox(strMsg);
return i <= 0;
}
bool CampoSetup::LurchRunning() const
{
//cerca Lurch che funziona come programma (esecuzione in modalita' avvio automatico)...
bool ok = SystemRunning("Lurch", wxEmptyString);
if (!ok)
{
//...se non lo trova cerca il solo Authoriz sempre come programma...
ok = SystemRunning("Authorization", wxEmptyString);
//se non trova nulla cerca Lurch come servizio...
if (!ok)
{
int year = 0;
wxString strSrv = "127.0.0.1";
ok = ServerLogin(year, strSrv) != 0xFFFF;
}
}
return ok;
}
bool CampoSetup::CampoRunning() const
{
//ricerca di campo.aut per avere la lista dei moduli
//prima tenta con aggiornamento da disco...
wxString strInstallPath = "../install.ini";
//...poi con aggiornamento da CD
if (!wxFileName::FileExists(strInstallPath))
strInstallPath = "../../campo/install.ini";
//fa un giro sull'install.ini alla ricerca di tutti i moduli (sono i paragrafi lunghi 2) installati (se aggiornamento..
//..da disco) o da installare (se sta installando da CD)
wxArrayString asModuli;
if (wxFileName::FileExists(strInstallPath))
{
wxString strModulo;
long nIndex;
CampoIniFile iniInstall(strInstallPath, strModulo);
for (bool ok = iniInstall.GetFirstGroup(strModulo, nIndex); ok; ok = iniInstall.GetNextGroup(strModulo, nIndex))
{
if (strModulo.Len() == 2)
asModuli.Add(strModulo); //aggiunge all'array tutti i moduli che trova in install.ini
}
}
else //non trova nessun install.ini (non dovrebbe mai accadere) e tenta i moduli pi<70> importanti
{
asModuli.Add("ba");
asModuli.Add("cg");
asModuli.Add("ve");
asModuli.Add("mg");
asModuli.Add("lv");
}
//scandisce l'array dei moduli alla ricerca di un eventuale programma di campo ancora running a sua insaputa
wxString strAppName;
for (size_t i = 0; i < asModuli.GetCount(); i++)
{
for (size_t j = 0; j <= 9; j++)
{
strAppName = asModuli[i];
strAppName += ('0'+j);
wxSingleInstanceChecker sicProgram(strAppName);
if (sicProgram.IsAnotherRunning())
{
strAppName << " <20> in esecuzione! E' necessario terminarlo utilizzando il Task Manager di Windows";
ErrorBox(strAppName);
return true;
}
}
}
return false; //campo non sta andando
}
//metodo principale che sceglie la modalita' di lancio del programma
void CampoSetup::OnTimer(wxTimerEvent& WXUNUSED(e))
{
//controllo di eventuali Campo o servers attivi e conseguente interruzione dell'installazione
if (LurchRunning())
{
if (YesNoBox("Per poter aggiornare/installare il programma CAMPO deve temporaneamente essere disattivato il gestore delle licenze!\nPrima di disattivare il gestore delle licenze accertarsi che tutti gli utenti spengano il programma CAMPO!!\nProseguire con la disattivazione?"))
const long lStop = StopLurch();
else
{
m_pMainFrame->Destroy();
return;
}
}
if (SystemRunning("ba0", "Uscire dal programma CAMPO prima di procedere con l'aggiornamento/installazione!") ||
SystemRunning("ba1", "Uscire dal programma di manutenzione di CAMPO\n prima di procedere con l'aggiornamento/installazione!"))
{
m_pMainFrame->Destroy();
return;
}
if (CampoRunning())
{
ErrorBox("Un applicativo di CAMPO <20> ancora in esecuzione!\nL'installazione sar<61> interrotta immediatamente");
m_pMainFrame->Destroy();
return;
}
wxFileName strPath(argv[0]);
strPath.MakeAbsolute();
strPath.SetCwd();
//path del programma setup.exe in esecuzione; serve in seguito in quanto alcuni metodi (tipo la GetAllFiles)..
//..fanno perdere questo path
m_strSetupPath = strPath.GetPath();
//attenzione!!! il path DEVE terminare con "\" senn<6E> in base al tipo di chiamata (-uw,-uc,-ud) i rispettivi..
//..metodi funzionano a casaccio!!!
if (!m_strSetupPath.EndsWith(wxT("\\")))
m_strSetupPath << '\\';
wxString strCommand = argv[1];
if (strCommand.IsEmpty())
NormalSetup();
else
{
if (strCommand == "-ud")
DiskUpdate();
if (strCommand == "-uc")
ClientUpdate();
if (strCommand == "-uw")
InternetUpdate();
}
//finestrina x chiudere a mano il programma (sconsigliata causa lancio ba1.exe)
// ::wxMessageBox(wxT("Installazione terminata"), APPNAME, wxOK | wxICON_INFORMATION);
m_pMainFrame->Destroy();
}
bool CampoSetup::OnInit()
{
wxInitAllImageHandlers();
m_locale.Init();
m_pWizard = NULL; //finestra di programma nulla;deve esistere solo per il NormalSetup dove viene inizializzata
m_pMainFrame = new CampoFrame;
SetTopWindow(m_pMainFrame);
wxTimerEvent e(883);
AddPendingEvent(e);
return true;
}