/* * Metodo eseguito da un thread in background per la ricezione dati dal socket * La signature della funzione deve rispettare il delegato ThreadStart */ public void ThreadFcn() { int nread = 0; try { Byte[] myReadBuffer = new Byte[1024]; // Ricezione modifiche dal server while (!stop) { Console.WriteLine("In attesa di ricevere dati dal server..."); // Ricezione tipo modifica: u_short nread = Stream.Read(myReadBuffer, 0, sizeof(ushort)); if (!isReadCorrect(nread, sizeof(ushort))) { return; } // Conversione Network To Host Order ushort mod_convertito = BitConverter.ToUInt16(myReadBuffer, 0); int mod = IPAddress.NetworkToHostOrder((short)mod_convertito); Console.WriteLine("Tipo modifica: {0}", mod); // Ricezione PID del processo: DWORD // La dimensione della DWORD è pari a quella di un uint in C# nread = Stream.Read(myReadBuffer, 0, sizeof(uint)); if (!isReadCorrect(nread, sizeof(uint))) { return; } uint pid = BitConverter.ToUInt32(myReadBuffer, 0); Console.WriteLine("PID: {0}", pid); // Switch sul tipo della modifica switch (mod) { // Caso 0: aggiunta di una nuova applicazione case 0: // Ricezione lunghezza del nome dell'applicazione nread = Stream.Read(myReadBuffer, 0, sizeof(int)); if (!isReadCorrect(nread, sizeof(uint))) { return; } // Conversione Network To Host Order int len_conv = BitConverter.ToInt32(myReadBuffer, 0); Console.WriteLine("lunghezza convertita: {0}", len_conv); int name_len = IPAddress.NetworkToHostOrder(len_conv); Console.WriteLine("lunghezza nome: {0}", name_len); Byte[] buffer_name = new Byte[name_len]; String app_name = String.Empty; // Ricezione del nome dell'applicazione nread = Stream.Read(buffer_name, 0, name_len); if (!isReadCorrect(nread, name_len)) { return; } // Conversione in String try { app_name = System.Text.UnicodeEncoding.Unicode.GetString(buffer_name); app_name = app_name.Replace("\0", String.Empty); } catch (ArgumentException) { app_name = "Senza nome"; } Console.WriteLine("Nome dell'app: {0}", app_name); // Ricezione lunghezza dell'icona nread = Stream.Read(myReadBuffer, 0, sizeof(int)); if (!isReadCorrect(nread, sizeof(uint))) { return; } // Creazione dell'oggetto ApplicationItem con icona di default ApplicationItem app = new ApplicationItem(item.ContainerTab.MainWindow.defaultIcon); app.PID = pid; app.Name = app_name; // Conversione Network To Host Order int icon_conv = BitConverter.ToInt32(myReadBuffer, 0); int icon_len = IPAddress.NetworkToHostOrder(icon_conv); Console.WriteLine("lunghezza icona convertita: {0}", icon_len); // Se la dimensione dell'icona è valida, si sostituisce a quella di default if (icon_len != 0 && icon_len < 1048576) { Console.WriteLine("Icona presente"); // Ricezione icona (in blocchi da 1024 byte) Byte[] buffer_ICON = new Byte[icon_len]; int tot = 0, toread = 1024; while (tot != icon_len) { if (toread > icon_len - tot) { toread = icon_len - tot; } nread = Stream.Read(buffer_ICON, tot, toread); if (nread == 0) { Console.WriteLine("Connessione chiusa durante lettura"); return; } tot += nread; } if (tot != icon_len) { Console.WriteLine("Read fallita: {0}", nread); item.ContainerTab.MainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { item.ContainerTab.MainWindow.CloseTab(item.ContainerTab); })); } // Codice unsafe perché si fa uso di puntatori // Lettura dell'icona tramite la funzione importata e conversione in bitmap WPF unsafe { fixed(byte *buffer = &buffer_ICON[0]) { IntPtr Hicon = CreateIconFromResourceEx((IntPtr)buffer, (uint)icon_len, 1, 0x00030000, 48, 48, 0); if (Hicon != null) { BitmapFrame bitmap = BitmapFrame.Create(Imaging.CreateBitmapSourceFromHIcon(Hicon, new Int32Rect(0, 0, 48, 48), BitmapSizeOptions.FromEmptyOptions())); if (bitmap.CanFreeze) { bitmap.Freeze(); app.Icon = bitmap; } DestroyIcon(Hicon); } } } } // Aggiunta nuova applicazione e notifica del cambiamento nella lista item.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() => { lock (item.applications) { item.applications.Add(app); } })); item.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() => { item.listView_CollectionChanged(item.listView, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, app)); })); break; // Caso 1: rimozione di un'applicazione case 1: Console.WriteLine("Modifica: Rimozione"); // Rimozione dell'applicazione dalla lista Monitor.Enter(item.applications); foreach (ApplicationItem appItem in item.applications) { if (appItem.PID == pid) { Console.WriteLine("Rimozione applicazione: {0}", appItem.Name); Monitor.Exit(item.applications); this.item.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() => { lock (item.applications) { this.item.applications.Remove(appItem); } })); Monitor.Enter(item.applications); break; } } Monitor.Exit(item.applications); break; // Caso 3: cambio di focus case 2: Console.WriteLine("Modifica: Change Focus"); // Pulizia della selezione precedente this.item.ContainerTab.MainWindow.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() => { this.item.listView.SelectedItem = null; })); // Applicazione che perde il focus this.item.ContainerTab.MainWindow.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() => { // Aggiornamento lista app in foreground int index = this.item.ContainerTab.MainWindow.foregroundApps.IndexOf(new ForegroundApp(item.ContainerTab.foregroundApp, 0)); if (index != -1) { if (--this.item.ContainerTab.MainWindow.foregroundApps[index].Count <= 0) { this.item.ContainerTab.MainWindow.foregroundApps.RemoveAt(index); } } })); // Ricerca delle applicazioni coinvolte nel cambiamento Monitor.Enter(item.applications); foreach (ApplicationItem appItem in item.applications) { // Applicazione che guadagna il focus if (appItem.PID == pid) { Console.WriteLine("Pid: {0} - applicazione: {1}", pid, appItem.Name); Monitor.Exit(item.applications); this.item.ContainerTab.MainWindow.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() => { lock (item.applications) { // Evidenziazione elemento nella tab appItem.IsFocused = true; this.item.listView.SelectedItem = appItem; this.item.ContainerTab.foregroundApp = appItem.Name; // Aggiornamento lista delle app in foreground int index = this.item.ContainerTab.MainWindow.foregroundApps.IndexOf(new ForegroundApp(appItem.Name, 0)); if (index != -1) { this.item.ContainerTab.MainWindow.foregroundApps[index].Count++; } else { ForegroundApp newapp = new ForegroundApp(appItem.Name, 1); this.item.ContainerTab.MainWindow.foregroundApps.Add(newapp); if (!this.item.ContainerTab.MainWindow.foregroundBox.IsEnabled) { this.item.ContainerTab.MainWindow.foregroundBox.SelectedItem = newapp; } } } })); Monitor.Enter(item.applications); } else if (appItem.IsFocused) { appItem.IsFocused = false; } } Monitor.Exit(item.applications); // Aggiornamento delle percentuali item.Dispatcher.Invoke(DispatcherPriority.Send, new Action(() => { item.percentageUpdate(); })); break; case 3: break; default: Console.WriteLine("Modifica sconosciuta"); break; } } Console.WriteLine("Thread - terminata ricezione dati dal server"); } catch (NullReferenceException) { ExceptionHandler.ReceiveConnectionError(item); } catch (IOException) { ExceptionHandler.ReceiveConnectionError(item); } catch (ObjectDisposedException) { ExceptionHandler.ReceiveConnectionError(item); } catch (ArgumentOutOfRangeException) { ExceptionHandler.ReceiveConnectionError(item); } catch (OutOfMemoryException) { ExceptionHandler.MemoryError(item.ContainerTab.MainWindow); } }
//metodo eseguito da un thread in background per la ricezione dati dal socket public void ThreadFcn() //la signature della funzione deve rispettare il tipo delegate { int nread = 0; Byte[] myReadBuffer = new Byte[1024]; try { //Ricezione modifiche dal server while (!stop) { Console.WriteLine("In attesa di ricevere dati dal server..."); //Ricezione tipo modifica e PID : u_short + DWORD nread = Stream.Read(myReadBuffer, 0, sizeof(ushort)); //catturare IOException if (nread == 0) { Console.WriteLine("Connessione chiusa durante lettura"); break; } else if (nread != sizeof(ushort)) { Console.WriteLine("Read fallita"); //Il client chiude mainWindow.atClosingTime(); } //ha letto il tipo di modifica ushort mod_convertito = BitConverter.ToUInt16(myReadBuffer, 0); Console.WriteLine("mod_convertito: {0}", mod_convertito); int mod = IPAddress.NetworkToHostOrder((short)mod_convertito); Console.WriteLine("Tipo modifica: {0}", mod); //Leggo il PID del processo nread = Stream.Read(myReadBuffer, 0, sizeof(uint)); //leggo la dimensione di un DWORD(long in c++), uint (c#) if (nread == 0) { Console.WriteLine("Connessione chiusa durante lettura"); break; } else if (nread != sizeof(uint)) { Console.WriteLine("Read fallita"); mainWindow.atClosingTime(); } //salvo il pid uint pid = BitConverter.ToUInt32(myReadBuffer, 0); Console.WriteLine("PID: {0}", pid); switch (mod) { case 0: //ricevo lunghezza del nome dell'applicazione nread = Stream.Read(myReadBuffer, 0, sizeof(int)); if (nread == 0) { Console.WriteLine("Connessione chiusa durante lettura"); break; } else if (nread != sizeof(int)) { Console.WriteLine("Read fallita"); mainWindow.atClosingTime(); } //salvataggio lunghezza del nome int len_conv = BitConverter.ToInt32(myReadBuffer, 0); Console.WriteLine("lunghezza convertita: {0}", len_conv); int name_len = IPAddress.NetworkToHostOrder(len_conv); Console.WriteLine("lunghezza nome: {0}", name_len); Byte[] buffer_name = new Byte[name_len]; String app_name = String.Empty; //Lettura del nome dal socket nread = Stream.Read(buffer_name, 0, name_len); if (nread == 0) { Console.WriteLine("Connessione chiusa durante lettura"); break; } else if (nread != name_len) { Console.WriteLine("Read fallita"); mainWindow.atClosingTime(); } //conversione in string app_name = System.Text.UnicodeEncoding.Unicode.GetString(buffer_name); app_name = app_name.Replace("\0", String.Empty); Console.WriteLine("Nome dell'app: {0}", app_name); //ricevo lunghezza dell'icona nread = Stream.Read(myReadBuffer, 0, sizeof(int)); if (nread == 0) { Console.WriteLine("Connessione chiusa durante lettura"); break; } else if (nread != sizeof(int)) { Console.WriteLine("Read fallita"); mainWindow.atClosingTime(); } ApplicationItem app = new ApplicationItem(mainWindow.defaultIcon); app.PID = pid; app.Name = app_name; //conversione icon_length in formato host int icon_conv = BitConverter.ToInt32(myReadBuffer, 0); int icon_len = IPAddress.NetworkToHostOrder(icon_conv); Console.WriteLine("lunghezza icona convertita: {0}", icon_len); //Sostituire l'icona di default if (icon_len != 0) { Console.WriteLine("Icona presente"); //Salvataggio icona Byte[] buffer_ICON = new Byte[icon_len]; int tot = 0, toread = 1024; while (tot != icon_len) { if (toread > icon_len - tot) { toread = icon_len - tot; } nread = Stream.Read(buffer_ICON, tot, toread); if (nread == 0) { Console.WriteLine("Connessione chiusa durante lettura"); break; } tot += nread; } if (tot != icon_len) { Console.WriteLine("Read fallita: {0}", nread); mainWindow.atClosingTime(); } unsafe { fixed(byte *buffer = new byte[1048576]) { uint i = 0; foreach (byte item in buffer_ICON) { buffer[i++] = item; } IntPtr Hicon = CreateIconFromResourceEx((IntPtr)buffer, i, 1, 0x00030000, 48, 48, 0); BitmapFrame bitmap = BitmapFrame.Create(Imaging.CreateBitmapSourceFromHIcon(Hicon, new Int32Rect(0, 0, 48, 48), BitmapSizeOptions.FromEmptyOptions())); bitmap.Freeze(); app.Icon = bitmap; DestroyIcon(Hicon); } } } // aggiunta nuova applicazione e notifica del cambiamento nella lista lock (MainWindow._syncLock) { mainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { mainWindow.applications.Add(app); })); mainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { mainWindow.listView_CollectionChanged(mainWindow.listView, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, app)); })); } break; case 1: // Modifica REMOVE Console.WriteLine("Modifica: Rimozione"); lock (MainWindow._syncLock) { try { foreach (ApplicationItem item in mainWindow.applications) { if (item.PID == pid) { Console.WriteLine("Rimozione applicazione: {0}", item.Name); mainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { mainWindow.applications.Remove(item); })); break; } } } catch (InvalidOperationException exc) { Console.WriteLine("Exception: {0}", exc.Message); } } break; case 2: //MODIFICA CHANGE FOCUS Console.WriteLine("Modifica: Change Focus"); lock (MainWindow._syncLock) { try { foreach (ApplicationItem item in mainWindow.applications) { if (item.PID == pid) { Console.WriteLine("Pid: {0} - applicazione: {1}", pid, item.Name); mainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { item.IsFocused = true; mainWindow.listView.SelectedItem = item; int index = mainWindow.foregroundApps.IndexOf(new ForegroundApp(item.Name, 0)); if (index != -1) { mainWindow.foregroundApps[index].Count++; // Aggiornamento conteggio app } else { mainWindow.foregroundApps.Add(new ForegroundApp(item.Name, 1)); } })); } else if (item.IsFocused) { Console.WriteLine("NO FOCUS-Pid: {0} - applicazione: {1}", item.PID, item.Name); mainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { item.IsFocused = false; int index = mainWindow.foregroundApps.IndexOf(new ForegroundApp(item.Name, 0)); if (--mainWindow.foregroundApps[index].Count <= 0) { mainWindow.foregroundApps.RemoveAt(index); } })); } } } catch (InvalidOperationException exc) { Console.WriteLine("Exception: {0}", exc.Message); } } mainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { mainWindow.percentageUpdate(null, null); })); break; default: Console.WriteLine("Modifica sconosciuta"); break; } //fine switch case } // fine while Console.WriteLine("Thread - terminata ricezione dati dal server"); } catch (NullReferenceException e) { Console.WriteLine("Exception message: {0}", e.Message); } catch (ThreadAbortException e) { /*TODO: da modificare/controllare*/ Console.WriteLine("Thread - caught ThreadAbortException - resetting."); Console.WriteLine("Exception message: {0}", e.Message); Thread.ResetAbort(); } catch (IOException e) { Console.WriteLine("Thread - caught IOException - connection closed"); Console.WriteLine("Exception message: {0}", e.Message); } }