private byte[] recCommFromServer() { byte[] res = new byte[commLength]; try { serverStream.Read(res, 0, res.Length); } catch (Exception e) when(e is IOException || e is ObjectDisposedException) { //L'oggetto Socket sottostante è chiuso. //-oppure - //La classe NetworkStream è chiusa. //-oppure - //Si è verificato un errore durante la lettura dalla rete. MyLogger.print("Errore nella comunicazione con il server"); MyLogger.debug(e.ToString()); throw new SocketException(); //mainWindow. } catch (Exception e) { MyLogger.debug(e.ToString()); throw; } return(res); }
/// <summary> /// delegato che inserisce il file in questione nell'appropriato hashSet /// </summary> /// <param name="fi"></param> private void checkFile(System.IO.FileInfo fi) { //MyLogger.add(fi.Name + "\n"); RecordFile thisFile = new RecordFile(fi); if (fi.Length == 0) { return; } FileStatus status = dim.UpdateStatus(thisFile); switch (status) { case FileStatus.New: MyLogger.print("nuovo: "); newFiles.Add(thisFile); MyLogger.print(fi.Name + "\n"); break; case FileStatus.Updated: MyLogger.print("aggiornato: "); updatedFiles.Add(thisFile); MyLogger.print(fi.Name + "\n"); break; case FileStatus.Old: MyLogger.debug("vecchio: "); MyLogger.debug(fi.Name + "\n"); //nothing to do break; } //MyLogger.add(thisFile); }
/// <summary> /// estraggo i vari record dei file e li sincronizzo con il server /// </summary> private void SyncAll() { //TODO:? implementare un meccanismo di abort tra un file e l'altro almeno. HashSet <RecordFile> buffer; MyLogger.print("Inizio Sincronizzazione:\n"); MyLogger.print("Sincronizzazione file aggiornati..."); buffer = d.getUpdatedFiles(); foreach (var f in buffer) { sm.syncUpdatedFile(f); d.confirmSync(f); } MyLogger.print("Ok.\n"); MyLogger.print("Sincronizzazione nuovi file..."); buffer = d.getNewFiles(); foreach (var f in buffer) { sm.syncNewFiles(f); d.confirmSync(f); } MyLogger.print("Ok.\n"); MyLogger.print("Sincronizzazione file cancellati..."); buffer = d.getDeletedFiles(); foreach (var f in buffer) { sm.syncDeletedFile(f); d.confirmSync(f, true); } MyLogger.print("Ok.\n"); MyLogger.print("Sincronizzazione completata.\n"); }
public void createAccount(string user, string password) { //string -> utf8 this.user = utf8.GetBytes(user); //per riferimento, così faccio con md5 //byte[] x = md5.ComputeHash(stream); //char di 16 caratteri. //string hex = BitConverter.ToString(x).Replace("-", string.Empty); //rappresentazione in esadecimale -> 32 caratteri. //return hex; SHA256 mySha256 = SHA256Managed.Create(); byte[] utf8psw = utf8.GetBytes(password); //hash(utf8(psw)) byte[] hashPswByte = mySha256.ComputeHash(utf8psw, 0, utf8psw.Length); string hex = BitConverter.ToString(hashPswByte).Replace("-", string.Empty); //rappresentazione in esadecimale -> 32 caratteri. this.hashPassword = utf8.GetBytes(hex); sendToServer(commAcc_str); //invio "[username]\r\n[sha-256_password]\r\n" byte[] userPassword = ConcatByte(this.user, separator_r_n); userPassword = ConcatByte(userPassword, this.hashPassword); userPassword = ConcatByte(userPassword, this.separator_r_n); sendToServer(userPassword); string risp = strRecCommFromServer(); switch (risp) { case commloggedok: MyLogger.print("Nuovo utente creato con successo"); return; break; case commDBERROR: MyLogger.print("Utente non valido, ritentare con un'altro utente"); throw new AbortLogicThreadException(); break; default: if (risp.Substring(0, 5) == commNameTooLongPARTIAL) { //nome utente troppo lungo. int maxLength = Int32.Parse(risp.Substring(5, 3)); mainWindow.Dispatcher.Invoke(mainWindow.DelShowOkMsg, "Errore, nome utente troppo lungo. Max: " + maxLength, MessageBoxImage.Error); throw new AbortLogicThreadException(); } else { throw new UnknownServerResponseException(); } break; } }
private void deleteFile(string fileName) { try { File.Delete(fileName); } catch (Exception e) { MyLogger.print("impossibile eliminare il file errato: " + fileName); MyLogger.debug(e); } }
/// <summary> /// classe ricorsiva che scandisce tutto il tree di directory e chiama un delegato sui singoli file /// </summary> /// <param name="root"></param> private void WalkDirectoryTree(System.IO.DirectoryInfo root, doOnFile_d doOnFile) { System.IO.FileInfo[] files = null; System.IO.DirectoryInfo[] subDirs = null; // First, process all the files directly under this folder try { //files = root.GetFiles("*.*"); files = root.GetFiles(); } // This is thrown if even one of the files requires permissions greater // than the application provides. catch (UnauthorizedAccessException e) { // da gestire il caso che non ho privilegi sufficienti ??? MyLogger.print(e.Message); } catch (System.IO.DirectoryNotFoundException e) { MyLogger.print(e.Message); throw; } //e se file fosse null ma ci fossero sotto cartelle?? non devo ritornare!! if (files != null) { foreach (System.IO.FileInfo fi in files) { // In this example, we only access the existing FileInfo object. If we // want to open, delete or modify the file, then // a try-catch block is required here to handle the case // where the file has been deleted since the call to TraverseTree(). //Console.WriteLine(fi.FullName); doOnFile(fi); } } // Now find all the subdirectories under this directory. subDirs = root.GetDirectories(); foreach (System.IO.DirectoryInfo dirInfo in subDirs) { // Resursive call for each subdirectory. WalkDirectoryTree(dirInfo, doOnFile); } }
private void buttStartStopSync_Click(object sender, RoutedEventArgs e) { bool toggleOn = !settings.getAutoSyncToggle(); settings.setAutoSyncToggle(toggleOn); //attivazione timer setAutoSync(toggleOn); if (toggleOn) { MyLogger.print("Sincronizzazione automatica attivata\n"); } else { MyLogger.print("Sincronizzazione automatica disattivata\n"); } }
private void SaveSettings() { BinaryFormatter formatter = new BinaryFormatter(); try { FileStream fout = new FileStream(SETTINGS_FILE_PATH, FileMode.Create); formatter.Serialize(fout, settings); fout.Close(); } catch (Exception e) { MyLogger.print("impossibile salvare file settings. le impostazioni attuali non saranno salvate"); //MyLogger.add(e.Message); } }
private void LoadSettings() { BinaryFormatter formatter = new BinaryFormatter(); FileStream fin; try { fin = new FileStream(SETTINGS_FILE_PATH, FileMode.Open); settings = (Settings)formatter.Deserialize(fin); fin.Close(); } catch (Exception e) { //se non esiste o non riesco a caricare settings: MyLogger.print("Impossibile trovare impostanzioni precedenti"); settings = new Settings(); } }
internal void logout() { try { sendToServer(commLogout_str); MyLogger.print("disconnessione in corso..."); //todo: da qui esce una socketexception da catchare waitForAck(commCmdAckFromServer); MyLogger.print("disconnessione effettuata\n"); mainWindow.logged = false; } catch (Exception e) { MyLogger.debug(e); } }
private void ManualSync() { MyLogger.print("Sincronizzazione in corso..."); bool wasAutoSyncOn = SyncTimer.IsEnabled; if (wasAutoSyncOn) { SyncTimer.Stop(); } needToSync = true; MakeLogicThreadCycle(); //permette al logicThread di procedere. if (wasAutoSyncOn) { SyncTimer.Start(); } }
//va chiamata quando desidero eseguire un controllo sulle modifiche effettuate nella dir public void scanDir() { //resetto le 4 categorie init(); //costriamo le 4 categorie (4 hashset) WalkDirectoryTree(myDir, doOnFile); deletedFiles = dim.getDeleted(); if (deletedFiles.Count > 0) { MyLogger.print("deleted files:"); foreach (var item in deletedFiles) { MyLogger.print(item); } } //MyLogger.line(); }
private void sendFileContent(RecordFile f) { try { const int bufsize = 1024; var buffer = new byte[bufsize]; int actuallyRead = 0; long sizeFile = 0; long totalBytesRead = 0; long nextStep = 0; long stepSize; using (var s = File.OpenRead(f.nameAndPath)) { sizeFile = s.Length; stepSize = (long)Math.Ceiling((double)sizeFile / 10); while ((actuallyRead = s.Read(buffer, 0, bufsize)) > 0) { serverStream.Write(buffer, 0, actuallyRead); //aggiorna progress bar totalBytesRead += actuallyRead; if (totalBytesRead > nextStep) { mainWindow.Dispatcher.BeginInvoke(mainWindow.DelSetProgressValues, sizeFile, 0, totalBytesRead); nextStep += stepSize; } } } serverStream.Flush(); mainWindow.Dispatcher.BeginInvoke(mainWindow.DelSetProgressValues, sizeFile, 0, sizeFile); } catch (Exception ex) { MyLogger.debug(ex.ToString()); MyLogger.print("errore leggendo il file"); throw; } }
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { MyLogger.print("Operazione in corso, attendere chiusura programma..."); if (interfaceMode == interfaceMode_t.busy) { string messageBoxText = "Interrompere l'esecuzione del programma e terminarlo?"; string caption = "Chiusura programma"; MessageBoxButton button = MessageBoxButton.YesNo; MessageBoxImage icon = MessageBoxImage.Warning; // Display message box MessageBoxResult wantToClose = MessageBox.Show(messageBoxText, caption, button, icon); if (wantToClose != MessageBoxResult.Yes) { //annullo la chiusura e.Cancel = true; } } LogicThreadShutDown(true); SaveSettings(); }
public void sendInitialBackup(List <RecordFile> RecordFileList) { //TODO! nota: durante l'upload di un file grosso deve aspettare la fine dell'upload per chiudersi. //forse è meglio che il main process non faccia join ma si chiuda brutalmente? sendToServer(commInitialBackup); waitForAck(commCmdAckFromServer); MyLogger.print("Primo Backup in corso..."); foreach (var rf in RecordFileList) { if (mainWindow.shouldIClose()) { throw new AbortLogicThreadException(); } MyLogger.debug("invio del file " + rf.nameAndPath); sendToServer(commIBNextFile); SendWholeFileToServer(rf); MyLogger.debug("completato\n"); } sendToServer(commIBSyncEnd); MyLogger.print("Primo Backup eseguito con successo\n"); }
private void newConnection() { MyLogger.print("Tentativo di connessione in corso..."); try { //se già connesso abort del thread logico if (clientSocket.Connected) { throw new DoubleConnectionException(); } //System.Net.IPAddress address = System.Net.IPAddress.Parse(serverIP); clientSocket.Connect(serverIP, serverPort); serverStream = clientSocket.GetStream(); serverStream.ReadTimeout = cnstReadTimeout; } catch (SocketException se) { MyLogger.print("Collegamento al server fallito\n"); MyLogger.debug(se); throw; } MyLogger.print("Connesso\n"); }
public static void print(Object o) { MyLogger.print(o.ToString()); }
/*-------------------------------------------------------------------------------------------------------------*/ /*---logic Tread methods---------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------*/ //siamo nel secondo thread, quello che non gestisce la interfaccia grafica. private void logicThreadStart() { MyLogger.debug("LogicThread starting"); //setto interfaccia a busy this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.busy); try //catch errori non recuperabili per il thread { //reset richieste eventualmente vecchie per il logic thread resetLogicThreadNeeds(); //avvio tmer per verifica abort signals periodicamente AbortTimer.Start(); //inizializzo oggetto per connessione con server sm = new SessionManager(settings.getIP(), settings.getPorta(), this); //bool connected = false; //gestione del login sm.login(settings.getUser(), settings.getPassw()); logged = true; //selezione cartella sm.setRootFolder(settings.getRootFolder()); //attiva modalità logged nella UI this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.logged); //voglio iniziare con una sync needToSync = true; //needToSync = false; //è la prima sync per questa connessione firstConnSync = true; //firstConnSync = false; //ciclo finchè la connessione è attiva. si esce solo con eccezione o con chiusura thread logico (anch'essa un'eccezione). while (true) { //verifica se deve sincronizzare if (needToSync) { this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.busy); MyLogger.print("AutoSync in corso\n"); // se è la prima sincronizzazione di questa connessione al server, crea DirMonitor if (firstConnSync) { firstConnSync = false; try { //init del dirMonitor d = new DirMonitor(settings.getRootFolder(), sm); } catch (EmptyDirException) { //se arrivo qui è perchè c'è stata la prima connessione, l'initial backup di una cartella vuota e il download delle recoverInfo sempre vuote. firstConnSync = true; } } else //non è la prima connessione { //scandisco root folder d.scanDir(); //sincronizzo tutte le modifiche SyncAll(); } needToSync = false; this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.logged); MyLogger.print("Completata\n"); } //verifica se deve richiedere l'intero ultimo backup if (needToRecoverWholeBackup) { this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.busy); sm.AskForSelectedBackupVersion(RecoveringQuery); needToRecoverWholeBackup = false; this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.logged); } //verifica se deve richiedere dati per ripristino di file vecchi if (needToAskRecoverInfo) { this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.busy); var recInfos = sm.askForRecoverInfo(); needToAskRecoverInfo = false; System.Diagnostics.Debug.Assert(recoverW != null); recoverW.Dispatcher.Invoke(DelSetRecoverInfos, recInfos); //qui l'interfaccia sarà resettata dalla recoverwindow che si chiude //this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.logged); } //recupera recoverRecord if (needToAskForFileToRecover) { this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.busy); //recupera file sm.askForSingleFile(fileToRecover); needToAskForFileToRecover = false; this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.logged); } WaitForSyncTime(); } } //fine try esterno catch (SocketException) { MyLogger.print("impossibile connettersi. Server non ragiungibile"); } catch (LoginFailedException) { MyLogger.print("errore nel login. Correggere dati di accesso o creare nuovo utente."); } catch (RootSetErrorException) { MyLogger.print("errore nella selezione della cartella. Correggere il path"); } catch (AbortLogicThreadException) { MyLogger.print("Connessione Interrotta\n"); MyLogger.debug("LogicThread closing per abort logic thread exception"); } catch (DirectoryNotFoundException) { MyLogger.print("impossibile trovare directory specificata. Selezionarne un'altra"); } catch (Exception e) //eccezione sconosciuta. { MyLogger.line(); MyLogger.debug(e.Message); MyLogger.line(); MyLogger.debug(e.ToString()); MyLogger.debug("LogicThread closing"); MyLogger.print("Errore sconosciuto. Chiusura connessione.\n"); } this.Dispatcher.BeginInvoke(DelSetInterfaceLoggedMode, interfaceMode_t.notLogged); //if (!TerminateLogicThread) //{ // //setta la UI in modalità unlocked a meno che non sia TerminateLogicThread settata, // //se no mainThread va in join e va in deadlock (non esegue invoke()) // this.Dispatcher.BeginInvoke(DelSetInterfaceLoggedMode, interfaceMode_t.notLogged); //} sm.closeConnection(); //disattivo il timer che sblocca periodicamente il logicThread affinchè controlli se deve abortire AbortTimer.Stop(); //this.Dispatcher.Invoke(DelSetInterfaceLoggedMode, interfaceMode_t.notLogged); logged = false; //TODO: ma quando chiudo recoverW diventa null? if (recoverW != null) { recoverW.Dispatcher.BeginInvoke(recoverW.DelCloseWindow); } return; //logic thread termina qui }
internal void AskForSelectedBackupVersion(MainWindow.RecoveringQuery_st recQuery) { int version = recQuery.versionToRecover; MyLogger.print("Ripristino della versione " + recQuery.versionToRecover + "... "); sendToServer(commRecoverBackup); waitForAck(commCmdAckFromServer); //seleziono versione sendToServer(version.ToString()); int fileCount = recQuery.recInfos.getVersionSpecificCount(version); try { for (int i = 0; i < fileCount; i++) { //legge nome del file string fileName = socketReadline(); string newPathAndName; //definisce percorso dove salvare il file if (recQuery.recoveringFolderPath != "") { //path da usare: quello specificato da utente System.Diagnostics.Debug.Assert(fileName.Contains(mainWindow.settings.getRootFolder())); //elimina la rootFolder. lascia // iniziale string localPath = fileName.Substring(mainWindow.settings.getRootFolder().Length); newPathAndName = recQuery.recoveringFolderPath.TrimEnd(Path.AltDirectorySeparatorChar) + localPath; } else { //path da usare: quello originale del file newPathAndName = fileName; } //apro il file FileStream fout; Directory.CreateDirectory(System.IO.Path.GetDirectoryName(newPathAndName)); try { fout = new FileStream(newPathAndName, FileMode.Create); } catch (Exception e) when(e is IOException || e is UnauthorizedAccessException) { //se file è protetto ne crea una copia a fianco newPathAndName += "-restoredCopy"; fout = new FileStream(newPathAndName, FileMode.Create); MyLogger.print("Impossibile ripristinare il file " + newPathAndName + ", salvo con suffisso \"restoredCopy\"\n"); } System.DateTime LastModifyDate; try { LastModifyDate = RecFileContent(newPathAndName, fout); fout.Close(); FileInfo fi = new FileInfo(newPathAndName); fi.LastWriteTime = LastModifyDate; } catch (CancelFileRequestException) { MyLogger.print("Operazione Annullata\n"); fout.Close(); deleteFile(newPathAndName); return; } catch (IOException) { MyLogger.popup("Impossibile accedere al file " + newPathAndName + " Operazione interrotta.", MessageBoxImage.Error); fout.Close(); deleteFile(newPathAndName); return; } } //mainWindow.Dispatcher.Invoke(mainWindow.DelShowOkMsg, "Ripristino versione completato!", MessageBoxImage.Information); //MyLogger.print("Ripristino versione " + recQuery.versionToRecover.ToString() + " riuscito"); MyLogger.popup("Ripristino versione " + recQuery.versionToRecover.ToString() + " riuscito", MessageBoxImage.Information); } catch (Exception e) { MyLogger.print("ripristino fallito"); mainWindow.Dispatcher.Invoke(mainWindow.DelShowOkMsg, "Ripristino versione fallita", MessageBoxImage.Error); MyLogger.debug(e.ToString()); return; } }
/// <summary> /// return true se ricezione corretta, false altrimenti /// </summary> /// <param name="fout">already opened output fileStream</param> /// <returns>last modify date of the file</returns> private System.DateTime RecFileContent(string FileNameAndPath, FileStream fout) { //ricezione hash byte[] hashReceived = new byte[32]; var count = serverStream.Read(hashReceived, 0, 32); string strHash = System.Text.Encoding.UTF8.GetString(hashReceived); //remove \r\n socketReadline(); //legge dimensione del file long sizeFile = Convert.ToInt64(socketReadline(), 16); //legge data_ultima_modifica file var lmfile = MyConverter.UnixTimestampToDateTime(Convert.ToInt64(socketReadline(), 16)); //data_rec sendToServer(commDataRec); int attempt = 0; do { //ricezione e salvataggio su disco. var buffer = new byte[1024]; int bytesRead; long totalBytesRead = 0; fout.Seek(0, SeekOrigin.Begin); //step della progress bar long stepSize = (long)Math.Ceiling((double)sizeFile / 10); long nextStep = 0; do { bytesRead = serverStream.Read(buffer, 0, buffer.Length); fout.Write(buffer, 0, bytesRead); totalBytesRead += bytesRead; //aggiorna progress bar if (totalBytesRead > nextStep) { mainWindow.recoverW.Dispatcher.BeginInvoke(mainWindow.recoverW.DelSetRecProgressValues, sizeFile, 0, totalBytesRead); nextStep += stepSize; } }while (totalBytesRead < sizeFile); mainWindow.recoverW.Dispatcher.BeginInvoke(mainWindow.recoverW.DelSetRecProgressValues, sizeFile, 0, sizeFile); if (totalBytesRead != sizeFile) { sendToServer(commSndAgain); attempt++; if (attempt < 5) { continue; } else { break; } } //calcolo e confronto hash var computedHash = RecordFile.calcHash(FileNameAndPath, fout); if (computedHash == strHash) { sendToServer(commDataAck); return(lmfile); } else { sendToServer(commSndAgain); attempt++; } }while (attempt < 5); MyLogger.print("errore nel download del file. impossibile effettuare il ripristino.\n"); //todo: catchare questa eccezione nelle funzioni chiamanti throw new CancelFileRequestException(); }
/// <summary> /// restitrusce true se login ha avuto successo. se no false. /// </summary> /// <param name="user"></param> /// <param name="password"></param> /// <returns></returns> public void login(string user, string password) { if (mainWindow.logged) { logout(); } if (!clientSocket.Connected) { newConnection(); } //string -> utf8 this.user = utf8.GetBytes(user); SHA256 mySha256 = SHA256Managed.Create(); byte[] utf8psw = utf8.GetBytes(password); //hash(utf8(psw)) byte[] hashPswByte = mySha256.ComputeHash(utf8psw, 0, utf8psw.Length); string hex = BitConverter.ToString(hashPswByte).Replace("-", string.Empty); //rappresentazione in esadecimale -> 32 caratteri. this.hashPassword = utf8.GetBytes(hex); sendToServer(commLogin_str); //invio "[username]\r\n[sha-256_password]\r\n" byte[] userPassword = ConcatByte(this.user, separator_r_n); userPassword = ConcatByte(userPassword, this.hashPassword); userPassword = ConcatByte(userPassword, this.separator_r_n); sendToServer(userPassword); switch (/*commloggedok)*/ strRecCommFromServer()) { case commloggedok: mainWindow.logged = true; break; case commloginerr: //create_ac? MyLogger.print("errore nel login\n"); bool wantNewAcc = (bool)mainWindow.Dispatcher.Invoke(mainWindow.DelAskNewAccount); if (wantNewAcc) { //newConnection(); createAccount(user, password); //login automatico mainWindow.logged = true; return; } else { mainWindow.logged = false; throw new LoginFailedException(); } break; case commAlreadyLogged: MyLogger.print("utente già connesso"); mainWindow.logged = false; throw new LoginFailedException(); break; default: mainWindow.logged = false; throw new LoginFailedException(); break; } }
public void askForSingleFile(RecoverRecord rr) { FileStream fout; string localFileName; MyLogger.print("Ripristino file in corso..."); sendToServer(commRecoverFile); waitForAck(commCmdAckFromServer); try { if (File.Exists(rr.rf.nameAndPath)) { //chiede se sovrascrivere string message = "file già esistente. si desidera sovrascriverlo?"; string caption = "Attenzione!"; bool wantOverwrite = (bool)mainWindow.recoverW.Dispatcher.Invoke(mainWindow.recoverW.DelYesNoQuestion, message, caption); if (!wantOverwrite) { //salvare con nome throw new IOException("need to save with name"); } } else { Directory.CreateDirectory(System.IO.Path.GetDirectoryName(rr.rf.nameAndPath)); } localFileName = rr.rf.nameAndPath; fout = File.Open(localFileName, FileMode.OpenOrCreate); } catch (Exception e) when(e is IOException || e is UnauthorizedAccessException) { //file omonimo esiste già o altri errori nell'aprire il file. apro una dialog di salvataggio Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog(); sfd.InitialDirectory = mainWindow.settings.getRootFolder(); sfd.FileName = rr.rf.getJustName(); Nullable <bool> result = sfd.ShowDialog(); localFileName = sfd.FileName; if (result == true) { try { fout = File.Open(localFileName, FileMode.Create); } catch (Exception) { //mainWindow.Dispatcher.Invoke(mainWindow.DelShowOkMsg, "Impossibile aprire il file", MessageBoxImage.Error); MyLogger.popup("Impossibile aprire il file. Operazione Annullata\n", MessageBoxImage.Error); MyLogger.print("Impossibile aprire il file. Operazione Annullata\n"); //annullo richiesta recupero di questo file return; } } else { MyLogger.print("Operazione Annullata\n"); //annullo richiesta recupero di questo file return; } } //invio nome singolo file sendToServer(rr.rf.nameAndPath + "\r\n" + rr.backupVersion.ToString() + "\r\n"); System.DateTime LastModifyDate; try { //ricevi contenuto file LastModifyDate = RecFileContent(localFileName, fout); } catch (CancelFileRequestException) { MyLogger.print("Operazione Annullata\n"); fout.Close(); deleteFile(localFileName); return; } catch (IOException) { MyLogger.popup("Impossibile accedere al file. Operazione annullata.", MessageBoxImage.Error); fout.Close(); deleteFile(localFileName); return; } fout.Close(); FileInfo fi = new FileInfo(localFileName); fi.LastWriteTime = LastModifyDate; MyLogger.print("completato.\n"); }