private static void HandleClientComm(object client) { TcpClient tcpClient = (TcpClient)client; TcpCommunicator <Message> tcpCommunicator = new TcpCommunicator <Message>(tcpClient); while (tcpClient.Connected) { Message message; try { message = tcpCommunicator.receive(); Console.WriteLine("Message reçu"); } catch (CommunicatorException ex) { Console.WriteLine(ex.Message); break; } Message response = null; switch (message.Type) { case Updater.Message.MessageType.GetFile: Console.WriteLine("Demande de fichier"); response = new Message(); response.Type = Message.MessageType.File; if (File.Exists(@"Data\" + message.Data)) { response.BinaryData = File.ReadAllBytes(@"Data\" + message.Data); } break; case Updater.Message.MessageType.GetManifest: Console.WriteLine("Demande de manifest"); response = new Message(); response.Type = Message.MessageType.Manifest; response.BinaryData = File.ReadAllBytes(ConfigurationManager.AppSettings["manifest"]); break; case Updater.Message.MessageType.End: Console.WriteLine("Demande de fin de connexion"); tcpClient.Close(); break; default: Console.WriteLine("Type de message inconnu"); break; } if (response != null) { try { Console.WriteLine("Envoi de la réponse"); tcpCommunicator.send(response); } catch (CommunicatorException ex) { Console.WriteLine(ex.Message); break; } } } }
public void Update() { this.UpdateState = State.CONNECTING; //Connexion au serveur TcpClient client = new TcpClient(); IPEndPoint serverEndPoint = new IPEndPoint(Dns.GetHostEntry("etaverne.ddns.net").AddressList[0], 5555); try { client.Connect(serverEndPoint); } catch (Exception ex) { this.UpdateState = State.CONNECTION_ERROR; return; } TcpCommunicator <Message> tcpCommunicator = new TcpCommunicator <Message>(client); //Récupèration des information de mise à jour this.UpdateState = State.MANIFEST; Message message = new Message(); message.Type = Message.MessageType.GetManifest; Message response; try { tcpCommunicator.send(message); response = tcpCommunicator.receive(); } catch (CommunicatorException ex) { this.UpdateState = State.CONNECTION_ERROR; client.Close(); return; } //Si le serveur a bien renvoyé le manifest if (!response.Type.Equals(Message.MessageType.Manifest)) { this.UpdateState = State.CONNECTION_ERROR; client.Close(); return; } //On charge les manifest XmlDocument manifest = new XmlDocument(); XmlDocument newManifest = new XmlDocument(); MemoryStream ms = new MemoryStream(response.BinaryData); newManifest.Load(ms); ms = new MemoryStream(File.ReadAllBytes(ConfigurationManager.AppSettings["manifest"])); manifest.Load(ms); string currentVersion = manifest.SelectSingleNode("version").Attributes["id"].InnerText; string remoteVersion = newManifest.SelectSingleNode("version").Attributes["id"].InnerText; //Si la version du serveur est différente de la version locale, on met à jour if (!currentVersion.Equals(remoteVersion)) { this.UpdateState = State.GET_FILES; //Création d'un dossier temporaire pour stocker les nouveaux fichiers if (Directory.Exists(@"Temp")) { DirectoryInfo directoryInfo = new DirectoryInfo(@"Temp"); foreach (FileInfo file in directoryInfo.GetFiles()) { file.Delete(); } foreach (DirectoryInfo dir in directoryInfo.GetDirectories()) { dir.Delete(true); } Directory.Delete(@"Temp", true); } Directory.CreateDirectory(@"Temp"); XmlNodeList currentFiles = manifest.SelectNodes("//fichier"); XmlNodeList remoteFiles = newManifest.SelectNodes("//fichier"); //Liste des fichiers à mettre à jour List <string> filesToUpdate = new List <string>(); //Pour chaque fichier dans le nouveau manifest foreach (XmlNode file in remoteFiles) { bool isOkay = false; string path = file.SelectSingleNode("path").InnerText; string version = file.SelectSingleNode("version").InnerText; //On vérifie dans le manifest si le fichier existe et si sa version correspond foreach (XmlNode currentFile in currentFiles) { string currentPath = currentFile.SelectSingleNode("path").InnerText; string currentFileVersion = currentFile.SelectSingleNode("version").InnerText; if (currentPath.Equals(path)) { isOkay = currentFileVersion.Equals(version); break; } } //Si il le faut, on met le fichier dans la liste des fichiers à mettre à jour if (!isOkay) { filesToUpdate.Add(path); } } //On récupère les fichiers non à jour int i = 0; foreach (string path in filesToUpdate) { Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => this.pgbarLoader.Value = i * 100 / filesToUpdate.Count)); i++; //On créée la demande de fichier message = new Message(); message.Type = Message.MessageType.GetFile; message.Data = path; response = null; try { tcpCommunicator.send(message); response = tcpCommunicator.receive(); } catch (CommunicatorException ex) { this.UpdateState = State.CONNECTION_ERROR; client.Close(); return; } //On vérifie le contenu de la réponse if (!response.Type.Equals(Message.MessageType.File) || response.BinaryData == null) { continue; } //Création des répertoires if (!Directory.Exists(@"Temp\" + path)) { Directory.CreateDirectory(@"Temp\" + path); Directory.Delete(@"Temp\" + path); } //Écriture du fichier using (FileStream fs = new FileStream(@"Temp\" + path, FileMode.Create, FileAccess.Write)) { fs.Write(response.BinaryData, 0, response.BinaryData.Length); } } //On copie les nouveaux fichiers dans le répertoire de l'application this.UpdateState = State.UPDATE; int length = Directory.GetFiles(@"Temp\", "*.*", SearchOption.AllDirectories).Length; i = 0; foreach (string dirPath in Directory.GetDirectories(@"Temp\", "*", SearchOption.AllDirectories)) { Directory.CreateDirectory(dirPath.Replace(@"Temp\", @"")); } foreach (string newPath in Directory.GetFiles(@"Temp\", "*.*", SearchOption.AllDirectories)) { Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => this.pgbarLoader.Value = i++ *100 / length)); File.Copy(newPath, newPath.Replace(@"Temp\", @""), true); } //On supprime les fichiers qui n'existent plus dans la nouvelle version foreach (XmlNode file in currentFiles) { bool exist = false; string path = file.SelectSingleNode("path").InnerText; foreach (XmlNode remoteFile in remoteFiles) { string remotePath = remoteFile.SelectSingleNode("path").InnerText; if (remotePath.Equals(path)) { exist = true; break; } } if (!exist) { File.Delete(@"" + path); } } } //On enregistre le nouveau manifest this.UpdateState = State.END; newManifest.PreserveWhitespace = true; newManifest.Save(ConfigurationManager.AppSettings["manifest"]); //On supprime le dossier temporaire if (Directory.Exists(@"Temp")) { DirectoryInfo directoryInfo = new DirectoryInfo(@"Temp"); foreach (FileInfo file in directoryInfo.GetFiles()) { file.Delete(); } foreach (DirectoryInfo dir in directoryInfo.GetDirectories()) { dir.Delete(true); } Directory.Delete(@"Temp", true); } message = new Message(); message.Type = Message.MessageType.End; try { tcpCommunicator.send(message); } catch (CommunicatorException) { } client.Close(); this.UpdateState = State.READY; }