//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 #endif #include #include #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, 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(APPNAME + wxT("\\DefaultIcon"), str); str = strExeFile.GetFullPath(); str += wxT(" \"%1\""); WriteRootRegistryKey(APPNAME + wxT("\\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ù 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"); // NOME fisso della cartella del CD, non mettere APPNAME 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à 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")); CampoIniFile CampoIniMain(strPrgLocPath + "/campo.ini", "Main"); InstallationType nInstType = CampoIniMain.GetInstallationType(); wxString strLnk = Product(); switch (nInstType) { case it_server: strLnk += " (Server)"; break; case it_client: strLnk += " (Client)"; break; default: 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, wxString strMsg) const { wxSingleInstanceChecker sicProgram(strAppName); strMsg.Replace(wxT("PRODUCT"), PRODUCT); 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ù 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 << " è 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 un eventuale setup già lanciato (tipico di utonti e della premiata ditta bibì & bibò) wxSingleInstanceChecker sicSetup("setup"); if (sicSetup.IsAnotherRunning()) { wxString msg; msg << "Una installazione di " << PRODUCT << " è già in esecuzione!"; ErrorBox(msg); m_pMainFrame->Destroy(); return; } //controllo di eventuali Campo o servers attivi e conseguente interruzione dell'installazione if (LurchRunning()) { wxString msg; msg << "Per poter aggiornare/installare il programma " << PRODUCT << " deve temporaneamente essere disattivato il gestore delle licenze!\n" << "Prima di disattivare il gestore delle licenze accertarsi che tutti gli utenti spengano il programma!!\n" << "Proseguire con la disattivazione?"; if (YesNoBox(msg)) StopLurch(); else { m_pMainFrame->Destroy(); return; } } if (SystemRunning("ba0", "Uscire dal programma PRODUCT prima di procedere con l'aggiornamento/installazione!") || SystemRunning("ba1", "Uscire dal programma di manutenzione di PRODUCT\n prima di procedere con l'aggiornamento/installazione!")) { m_pMainFrame->Destroy(); return; } if (CampoRunning()) { wxString msg; msg << "Un applicativo di " << PRODUCT << " è ancora in esecuzione!\n" << "L'installazione sarà interrotta immediatamente"; ErrorBox(msg); 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ò 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; }