lunedì 28 novembre 2011
#
Troppe informazioni = nessuna informazione, oppure disinformazione o anche misinformazione. Scrivo questo blog dopo aver guardato il simpatico video pubblicato da Andrea Zingoni e dopo aver partecipato a WPC ed all’ MVP Community Summit, la scorsa settimana, ci tengo a mettere i miei 2centesimi riguardo la troppa o troppo scarsa quantità di informazioni contraddittorie che arrivano relativamente a Silverlight, HTML5 e Javascript ecc.
Quanto dico è esclusivamente l’opinione che mi sono fatta ascoltando quanto è stato detto alla BUILD ufficialmente da Microsoft e quanto è stato riportato dai vari MVP nei loro interventi relativi a Windows 8, Windows RT, Metro, ovvero le tecnologie che stanno arrivando nel nostro futuro.
Windows 8 ucciderà il Desktop?
Assolutamente no, chi si è scaricato la developer preview ed ha guardato la sola interfaccia metro si è perso più della metà di quello che c’è dentro a Windows 8, i desktop implementeranno sia l’interfaccia desktop vedi Windows 7 che quella Metro, anche perché l’interfaccia Metro è un interfaccia studiata per i Touch, per quanto molto bella difficilmente permetterà di fare data entry simile a quello che facciamo in un ERP. Certo, apre nuove porte per quello che è la raccolta dati onsite, l’implementazione di interfacce semplici ed usabili anche in un officina, (per quanto qualcuno dovrà predisporre delle device a prova di guanti da meccanico e olio motore) ed apre nuove porte per poter fornire dati a chi non è in azienda, quindi un rich report all’amministratore delegato relativo all’ultima settimana da parte del commerciale piuttosto che l’analisi di un consulente sui concorrenti e chi più ne ha più ne metta. Ma il desktop rimane dov’è, e se qualcuno si è dato la briga di spulciare le cartelle di sistema della developer preview potrà osservare che il famigerato runtime di VB6 è ancora li, anche se non è detto vi rimarrà in seguito.
Metro è l’interfaccia di Microsoft per i tablet ARM?
Certo che si, e su questo tipo di device che non è x86 probabilmente ci sarà solo Metro. Microsoft al riguardo non ha detto nulla di ufficiale, la sola motivazione logica per cui posso supporlo è che non essendo devices x86 far funzionare il kernel di windows sarebbe piuttosto complicato ma siccome “mai dire mai” è la parola d’ordine, lo scopriremo il prossimo anno.
Cosa succede a Silverlight e alla programmazione XAML + .NET?
Assolutamente nulla, perché il sistema di sviluppo dedicato a Metro e WinRT permette di sviluppare in C# + XAML, oppure in HTML5 + Javascript (sottolineo l’oppure), oppure in C++ nativo. E se vi chiedete perché Microsoft abbia deciso di supportare HTML5 e Javascript rispondo: è logico, se vogliono che chi sviluppa con queste due tecnologie possa passare le proprie APP anche su Metro senza dover imparare nuove tecnologie o reingegnerizzare tutto. Pertanto avremo la possibilità di usare un numero maggiore di tecnologie ma non butteremo alle ortiche tutto quello che ci siamo studiati fino a qui.
Anche perché se il Desktop rimarrà dove si trova ancora molto a lungo, tutto quello che è il .NET framework e quello che si farà per i desktop resta dov’è, collegato a tastiera e mouse come sempre.
E allora?
L’invito è a tenere d’occhio ciò che succederà, scaricare le CTP, provare ciò che c’è di nuovo, essere pronti ad agire, pensare a come usare il nuovo hardware nelle nostre applicazioni. Guardare a quello che sta arrivando come ad una nuova opportunità per il business, invece che ad un nuovo ostacolo da superare per mantenere le nostre conoscenze al passo con lo sviluppo.
Sono quella del bicchiere mezzo pieno? Si, oppure non avrei iniziato la mia prima applicazione .NET con la Beta2 di Visual Studio 2005, la Beta2 di SQL Server 2005 e la Beta2 dei controlli Infragistics, consegnandola al cliente in produzione una settimana dopo che era uscita la RTM.
A voi la parola.
venerdì 14 ottobre 2011
#

Una eccezione sollevata da un servizio web WCF pubblicato su IIS se cercate di scaricare via SOAP un oggetto (ad esempio una immagine) che in Base64 è più lunga di 216-1 byte.
Per ovviare al problema dovete intervenire sull’applicazione client non sul server dove gira il servizio web, nel mio caso si tratta di una applicazione Winforms (per il test) i parametri devono essere inseriti nell’app.config, se fosse una applicazione web dovrei modificare il web.config.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ISoapWS" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65535" maxBufferPoolSize="500000" maxReceivedMessageSize="65535"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="64" maxStringContentLength="65535" maxArrayLength="65535"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/MyWebservice/ServiceClass.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISoapWS"
contract="SoapWsTest.ISoapWS" name="BasicHttpBinding_ISoapWS" />
</client>
</system.serviceModel>
</configuration>
Dovete modificare i seguenti parametri
- maxBufferSize="65535"
- maxBufferPoolSize="500000"
- maxReceivedMessageSize="65535"
- maxStringContentLength="65535"
- maxArrayLength="65535"
Ad un valore che ritenete sufficiente per le vostre esigenze. Attenzione che se non li modificate tutti, riceverete una ulteriore eccezione per ognuno dei parametri che non sono abbastanza grandi. E’ ovvio che i parametri sono arbitrari, se dovete scaricare immagini o documenti PDF o files molto grandi andate sui milioni senza paura e ricordate che Bas64 è uno dei più dispendiosi fra i formati di trasmissione dati.
Ieri ho bloggato una nota per alcune conversioni poco frequenti che ho dovuto fare a causa di una routine di checksum che ho scritto per Alberto. Oggi ho scoperto che la mia ottimistica versione era largamente superata dal meccanismo reale del calcolo del checksum, per riuscire a riprodurre il quale ho dovuto effettuare una serie di stranezze che vi listo di seguito nel caso abbiate la “fortuna” (poca) di scontrarvi con qualcosa di simile.
Leggere un sub-array da un byte array
byte[] sourceArray;
... //Qui mettete i bytes nell’array leggendo un file o una seriale
byte[] destArray = new byte[desiredSublength]
Array.Copy(sourceArray, StartIndex, destArray, DestStartIndex, Length);
Conversione dei bytes nei corrispondenti caratteri ascii
char[] chars = System.Text.Encoding.UTF8.GetChars(destArray);
Far diventare una porzione dell’array di caratteri una string
string subValue = new string(charsArray, startIndex, length);
Convertire la stringa rappresentante un numero esadecimale in un byte
byte myHexByte = Convert.ToByte("1C", 16);
Convertire un byte in una stringa rappresentante il numero in esadecimale
string hexString = Convert.ToString(myByteValue, 16);
Fate attenzione che la stringa sia correttamente upper o lower case
string lowerHex = hexString.ToLower();
string upperHex = hexString.ToUpper();
Questo perché db e DB sono lo stesso numero ma cambiano completamente se convertite la stringa in un char array
char[] hexLetters = upperHex.ToCharArray();
e poi convertite il char array in un byte array
byte[] bytesFromHexLetters = new byte[hexLetters.Length];
for (int i = 0; i < hexLetters.Length; i++)
{
bytesFromHexLetters [i] = Convert.ToByte(chars[i]);
}
Provate con le lettere esadecimali in upper e lower case e ve ne accorgete, e se mi chiedete, ma tutto in una routine di calcolo del checksum?
qui lo chiamiamo Ufficio Complicazione Affari Semplici, sembra essere spesso molto affollato.
mercoledì 12 ottobre 2011
#
Due operazioni certamente non quotidiane per chi come me si occupa solitamente di database e user interface, ma oggi, Alberto mi ha chiesto un piccolo aiuto con un array di byte e uno strano checksum e per poter fare le verifiche ho dovuto usare entrambe le cose in oggetto. Mi segno come si fa per ritrovarlo alla prossima:
Convertire un byte[] in uno short[] (o int16[]) ma sarebbe lo stesso con int32 o int64:
private short[] GetShortArray(byte[] pBaits)
{
int length = pBaits.Length / 2 + pBaits.Length % 2;
short[] ret = new short[length];
int j = 0;
for (int i = 0; i < pBaits.Length; i += 2)
{
ret[j] = BitConverter.ToInt16(pBaits, i);
j++;
}
return (ret);
}
Ovviamente per gli int32 si deve spostarsi di 4 byte, per gli int64 di 8 byte e così via.
short[] pippo = new short[] { 100, 156, 234, 322 };
byte[] pluto = new byte[pippo.Length * 2];
int j = 0;
for (int i = 0; i < pippo.Length; i++)
{
byte[] pezzo = BitConverter.GetBytes(pippo[i]);
pluto[j] = pezzo[0];
j++;
pluto[j] = pezzo[1];
j++;
}
short[] resultShort = GetShortArray(pluto);
Il programmino becero qui sopra fa un test con questo risultato:

Ovviamente ci sono modi + eleganti di procedere all’estrazione dei byte e se i byte vi arrivano da una seriale già in riga potete convertirli velocemente come è successo a me.
Convertire un numero in una stringa in formato binario:
Se vi dovesse necessitare esaminare un numero intero o un byte per fare un Or oppure uno Xor, il metodo migliore è verificare i bit che lo compongono, ovviamente c’è la calcolatrice scientifica di windows, grazie al cielo, ma se ne avete un array intero è lungo quindi ecco come fare in C#:
private string GetBitString(byte pVal)
{
return (Convert.ToString(pVal, 2));
}
private string GetOctalString(byte pVal)
{
return (Convert.ToString(pVal, 8));
}
Come vedete ho fatto due metodi solo per mostrare che il secondo parametro è la base in cui rappresentare il numero, pertanto 2 per un numero binario, 8 per un ottale, 16 per un esadecimale e così via. Il risultato del mio test è:

Verificate a manina e vedrete che è corretto, pertanto grazie a .Net.
domenica 9 ottobre 2011
#
Stiamo implementando un servizio interno (interno vuol dire che lavora in una intranet), per uno dei software della mia azienda, il servizio scambia messaggi con i pc client dove gira l’applicazione. I dati scambiati sono spediti come una classe XML ad un HTTP Listener.
Sembrava tutto semplice eccetto che, quando la classe XML arrivava al listener, il deserializzatore dava i numeri dicendo che la classe non era correttamente formattata.
Dopo una serie di approfondite verifiche sul nostro codice (Io parto sempre dal presupposto che le probabilità che abbia fatto dei danni è maggiore nel codice scritto da me rispetto a quello scritto in una libreria di sistema o un componente di terzi.) Non trovando nulla nel codice dei metodi di serializzazione e deserializzazione, abbiamo predisposto uno sniffer sui dati che arrivavano al listener nella response, abbiamo scoperto che i dati serializzati avevano 3 bytes che precedevano <?xml l’iniziale di tutti i files XML, in esadecimale si tratta dei valori EB BB BF, non capivamo cosa fosse e dopo aver passato alcuni momenti a pensare che cosa potesse esserci di sbagliato nel nostro codice per produrre questo problema, abbiamo fatto una ricerca su internet e abbiamo imparato qualcosa di importante (come sempre non si finisce mai di imparare…) Ad ogni modo, abbiamo scoperto che i tre caratteri invisibili sono un BOM (Byte Order Mark – Segno di Ordinamento dei Byte) che è automaticamente aggiunto dai sistemi di serializzazione quando si effettua un encoding in UTF-8. Notepad, Notepad++ e altri editor di testo o lettori di XML e testo ignorano il BOM pertanto non ci accorgeremo mai di lui ma si trova li. Il problema del mio servizio era dovuto al fatto che deserializzando da una stringa, i tre caratteri non venivano eliminati e il metodo di deserializzazione dava un errore dicendo che c’erano dei caratteri non compatibili all’inizio della classe.
C’è un modo per evitare il problema del BOM? Certo è uno dei parametri forniti al serializzatore da XmlWriterSettings
XmlWriterSettings xstt = new XmlWriterSettings();
xstt.Encoding = Encoding.UTF8 : new UTF8Encoding(false);
using (XmlWriter writer = XmlWriter.Create(stream, xstt))
{
...
}
Usando questa opzione per serializzare la classe, evitiamo che venga generato il BOM e quindi i problemi di deserializzazione.
Spero che questo articolo possa dare una mano a qualcuno con lo stesso problema risparmiandogli tempo e frustrazioni. 
mercoledì 5 ottobre 2011
#
Fra ieri e oggi, abbiamo perso circa 8 ore di lavoro 4 x 2 persone per correre dietro al problema in oggetto. Una classe Data Provider usata N volte nei nostri progetti, di punto in bianco ha cambiato modo di funzionare, producendo errori incomprensibili.
Antefatto: Sto testando una serie di classi per una applicazione usando una semplice applicazione di test, visto che ho 2 diversi database su cui faccio i test, ho inserito una stringa di connessione in una textbox precompilata, in modo che posso cambiarla al volo.
Data Source=NomeServer;Initial Catalog=NomeDatabase;Password=LaPassword;User ID=LUtente;
La password era nella forma qui sopra. Nei vari test che ho fatto, uno di essi utilizza una classe DataProvider in cui c’è un Dataset, contenente una DataTable, governata da un SqlDataAdapter, 4 SqlCommand, una SqlConnection. Queste classi sono quelle che usualmente utilizziamo per il CRUD di tutte le tabelle e hanno sempre funzionato correttamente. Ieri sera invece una operazione di tipo Fill (chiamata alla Fill del DataAdapter) AddRow, Update (chiamata alla Update del DataAdapter) dava un errore dicendo che l’utente non aveva diritto di eseguire il login a SQL Server.
Dopo 3 ore di debug passo passo e un paio di tentativi di taglio di vene per lungo, abbiamo scoperto che il DataAdapter, dopo la chiamata alla Fill eliminava la password dalla proprietà ConnectionString dell’oggetto SqlConnection in automatico. Siccome era una delle classi che usiamo quotidianamente in tutte le nostre applicazioni abbiamo finito per domandarci come fosse possibile che fino a ieri funzionasse tutto.
Abbiamo fatto un nuovo test debuggando una delle nostre applicazioni e verificato una delle nostre connection string applicative scoprendo con gioia di non essere del tutto pazzi, ma che il problema era determinato dal fatto che la connection string avrebbe dovuto essere così:
Data Source=NomeServer;Initial Catalog=NomeDatabase;Password=LaPassword;User ID=LUtente;Persist Security Info=true;
Pertanto, se per caso vi capitasse che un DataAdapter dopo la prima chiamata ad uno dei suoi command si mangi la password, il motivo è questo. La clausola Persist Security Info è fra quelle “sconsigliate” e in sua assenza, dopo una apertura della connection a SQL Server, la password viene eliminata. E’ una cosa mi dicono essere logica e viene fatta per questioni di sicurezza. Questo tipo di problema riesce a farti sentire un idiota, anche perché uno si chiede, ma come è possibile che non mi sia mai successo da quando lavoro con SQL Server (2003) e .Net.
martedì 27 settembre 2011
#
Un post annotazione, per non dimenticare come al solito.
Creando un nuovo Webservice usando un progetto WCF Service application, il sistema come sempre propone di debuggarlo sul webservice locale, se però dobbiamo fare dei test da macchine diverse per quel che riguarda il Client del nostro Webservice in fase di sviluppo potrebbe risultare difficile connettersi al Web Server di sviluppo, pertanto è opportuno pubblicare l’applicazione su IIS. per farlo bisogna fare una modifica alla configurazione dell’applicazione:

Dopo questa operazione, la cartella del vostro progetto diverrà una virtual directory sul Website di default di IIS

Importante!!! fate questa operazione o non funzionerà nulla o quasi, perché la virtual directory di IIS non riconosce bin\debug o bin\release o nel nostro caso bin\x86\debug.
Fatto questo, se siete su una macchina a 64bit e la vostra applicazione è compilata a 32bit è necessario indicare ad IIS che volete far funzionare applicazioni a 32Bit sull’application pool usato da ASP.Net pertanto aprite il manager di IIS

Selezionate l’application pool dell’applicazione.

Cliccate sugli Advanced settings dell’application pool.

Attivate le applicazioni a 32 bit e fate il restart del Website.
Se lanciando la web application ricevete questa schermata:

Il Webservice funziona perfettamente, vi manca solo una pagina di benvenuto, ma utilizzando lo startup multiplo dal menu
Solution > Tasto destro > Properties
E indicando di far partire il webservice e una Applicazione Windows Forms di Test, potete fare una Webreference al vostro Webservice e fare il debug dei webmethods.
Buon lavoro a tutti
Una lezione un po' anomala prima della numero 8 che proseguirà il normale flusso della serie di lezioni di pesca in questa lezione parliamo un po' di come crearsi delle librerie di codice riusabile, mentre nel nostro progetto compariranno "magicamente" due librerie che sono state sviluppate nella serie di articoli "Fritto Misto" aggiornate al framework 4.0. Ne approfitteremo per illustrare come si Estende una classe .Net del framework e per aggiornare alcune cose del nostro progetto prima di proseguire con una lezione dedicata alla serializzazione XML "seria".
Il Link del codice a corredo della lezione
Il Link per lo scaricamento del Webcast
mercoledì 14 settembre 2011
#
Dopo una lunga pausa proseguo la serie dei webcast dedicati agli sviluppatori principianti proseguendo con una lezione dedicata a mostrare l’uso dell’ereditarietà, l’uso di enumerazioni, l’uso di collezioni in una classe e ovviamente come serializzarla e deserializzarla in modo standard. Inoltre dimostro l’uso del sort all’interno di una collezione e come creare una ToString alternativa utilizzando i dati ordinati.
A questo indirizzo potete scaricare il webcast.
A questo link il codice a corredo della lezione
Un Webcast di tipo Sistemistico per spiegare come installare SQL Server Express edition configurandolo in modo professionale, era dai tempi di MSDE che non replicavo questo tipo di post, pertanto ho ritenuto opportuno farlo, soprattutto perché mi sono trovata da un paio di clienti ove ho trovato la classica installazione Avanti –> Avanti –> Invio e quindi ho creduto opportuno dare modo anche a chi non è un sistemista esperto di sapere come e soprattutto perché fare determinate operazioni quando si installa SQL Server. Replicherò anche con una versione non express prossimamente, aggiungendo anche la parte di configurazione degli utenti di servizio.
Tag di Technorati:
SQL,
Install,
SqlExpress A questo indirizzo potete scaricare il webcast.
mercoledì 10 agosto 2011
#
Oggi, lavorando ad un piccolo progetto che coinvolgeva l’oggetto .NET nel titolo, ci siamo imbattuti in una stranezza, ovvero se trasmettevo tramite una HTTP Get un dato al listener che conteneva una stringa (“Buongiorno, sono la stringa”) arrivava esattamente come trasmessa, mentre se trasmettevo la serializzazione di una classe in XML la stringa risultante era diversa da quella trasmessa e davanti al <?xml c’erano 3 caratteri strani, ovvero una i con la umlaot, una doppia virgoletta chiusa e un punto di domanda rovescio. Rovistando sulla stringa ci siamo accorti che la serializzazione XML per default inserisce come primo carattere della stringa/file serializzato il carattere unicode \UFEFF, che è un carattere non visibile (lo scarta automaticamente anche notepad), questo carattere serve a chi poi riceve la stringa per capire se si tratta di testo BigEndian o LittleEndian, potete leggere il dettaglio su Wikipedia se siete curiosi. Questo carattere unicode può essere fatto omettere al serializzatore .NET inserendo negli XmlWriterSettings che si passano all’XmlSerializer il parametro Encoding=false se non vogliamo questo carattere. Ovviamente togliere il carattere non è esattamente la soluzione al problema, anche se può essere un buon workaround, la soluzione vera è fare un UrlEncoding della stringa XML prima di spedirla con il GET, oppure, se vogliamo essere categorici, possiamo convertire la stringa XML in un Base64 e riconvertirla in unicode all’arrivo al listener.
Usualmente ci si accorge di questo errore perché deserializzando la classe si riceve la seguente eccezione:
System.Xml.XmlException
Data at the root level is invalid. Line 1, position 1.
ecco invece uno screenshot del formato della stringa XML

giovedì 26 maggio 2011
#
Probabilmente è una notizia arcinota da chi quotidianamente lavora con Plesk, io invece lo uso molto raramente, e lo conosco veramente al minimo. Però, se come me avete un virtual server aziendale, quasi tutti i provider ve lo installano come oggetto per la creazione di domini e siti, presumo per evitare di avere milioni di chiamate dagli utenti inesperti come me.
E’ normale che una azienda abbia più di un dominio (.it, .com, .eu, .net) e chi più ne ha più ne metta, collegati al proprio sito, ma ovviamente non facciamo una copia del sito per ogni dominio, oppure diverrebbe deprimente tenerli aggiornati.
Nel mio caso, il sito della mia azienda è stato creato con un DotNetNuke, che è così gentile da permettere non solo di mappare più domini su uno stesso portale, ma permette anche, volendolo, di avere più portali diversi sullo stesso DNN.
Entrando dentro a Plesk, quando devi mappare i domini secondari ti verrebbe naturale generare un nuovo dominio, ma la generazione di un nuovo dominio da parte di Plesk ha solo 3 opzioni, dominio fisico, forward, frame forward. Nessuno dei tre è quello che vogliamo noi.
Infatti non è quello che dobbiamo fare. Per mappare più domini su un singolo DotNetNuke usando Plesk, bisogna selezionare il dominio fisico e generare dei Domain Alias. Uno per ogni dominio da mappare. Operazione da 30 secondi, basta infatti indicare il nome di dominio e selezionare la checkbox WEB, salvando il tutto.
Fatto questo, si passa a DotNetNuke, si va sull’host (
i friulani sanno perché rido) e si aggiunge al portale che deve mapparli, i domini prescelti usando l’opzione portal alias. L’effetto è immediato.
sabato 21 maggio 2011
#
In questa sesta lezione di pesca, proseguiamo quanto impostato nella scorsa lezione e creiamo la nostra prima collezione tipizzata di classi di tipo Competence. Generiamo la bozza della classe Developer, la classe principale di questo piccolo progetto e proseguiamo verificando come serializzare il nostro Developer su disco e rigenerare la classe leggendola da disco.
Codice a corredo della lezione 6
In caso non foste in grado di vedere direttamente il filmato, il link al webcast per lo scaricamento è questo.
domenica 15 maggio 2011
#
Siamo arrivati alla quinta lezione di C# della serie, abbiamo concluso la gestione della nostra prima classe, la classe persona, pertanto per proseguire e presentare tutti gli aspetti di quello che si può fare con C# iniziamo a pensare a una piccola applicazione, che ci permetterà di spiegare le enumerazioni, le collezioni, l'ereditarietà, la serializzazione XML e probabilmente molte altre cose che verranno.
Avendo come base la classe persona, ho deciso di creare una classe per gestire il curriculum di un programmatore con informazioni anagrafiche, un minimo di informazioni "fiscali", una collezione di competenze che descrivano quello che lui sa fare ed una collezione di lingue conosciute con la loro descrizione. In seguito magari potremo estendere ulteriormente il tutto.
In questo Webcast, oltre a spiegare a grandi linee cosa faremo nelle prossime lezioni, creiamo una Enumerazione e vediamo come si usa, e creiamo la classe base Competence per descrivere le competenze del programmatore, gli aggiungiamo funzionalità e spieghiamo come salvare su disco le informazioni usando XML e spiegando le basi della serializzazione (qualcosa di non nuovo a questo blog, che però in un webcast permette di approfondire i vari concetti di base).
Come sempre buona “pesca” e alla prossima lezione.
Il link al codice sorgente della quinta lezione
Tag di Technorati:
C#,
class,
enum Il link al webcast se avete problemi a visualizzarlo direttamente è questo: Un po' piu' di hello World - lezione 5
domenica 8 maggio 2011
#
Come promesso al Workshop, pubblico oggi il webcast della sessione effettuata il 28/04/2011 al Workshop gratuito Spring Blossoms 2011, in questa sessione ho spiegato le basi dell’uso di applicazioni multithreading in C# che interagiscono con l’interfaccia utente di una applicazione Windows Forms.
In questo webcast, c’è una parte di spiegazione su slide e una parte, abbastanza estesa di spiegazione sul codice demo.
Il codice a corredo si trova al link postato in fondo a questo post. Pertanto Buona visione e ascolto e per ogni domanda, quesito, dubbio, errore, omissione, potete usare i commenti o un messaggio inviato direttamente dal link in cima al blog.
Il codice demo a corredo del progetto
venerdì 6 maggio 2011
#
Lo scorso 5 maggio, in ufficio è saltata la corrente, si sono spenti tutti i server e c’è stato un problema sul restart del domain controller, pertanto, senza accorgerci della cosa, ci siamo trovati a lavorare con la data di Team Foundation Server modificata all’ 8/5/2011. La cosa è stata sistemata non appena qualcuno ha guardato il calendario, cioè a metà pomeriggio 

.
Intanto erano stati fatti alcuni checkin di varie modifiche. Ci siamo accorti che questo era un problema poco fa, quando cercando di fare un Checkin, il TFS ha dato questo messaggio agghiacciante.
TF54000: Cannot update data because the server clock may have been set incorrectly. Contact your Team Foundation Server Administrator.
Siccome l’administrator sono io non sapevo cosa fare anche dopo essermi contattata
quindi ho fatto un giro sui forum Microsoft e scoperto che potevo fare 2 cose:
- Aspettare di fare il checkin fino a lunedì prossimo (fattibile ma non proprio bellissimo)
- Andare a modificare i Changeset del TFS con la data sbagliata.
ovviamente l’opzione scelta è stata la seconda, posto qui lo script lanciato sul SQL Server del TFS per rimettere tutto a posto:
UPDATE tbl_ChangeSet
SET CreationDate = CreationDate -3 WHERE CreationDate > GETDATE()
Questo ha corretto tutti i changeset errati riportandoli alla data giusta togliendo 3 giorni alla data impostata.
Tag di Technorati:
TFS,
SQLserver
martedì 3 maggio 2011
#
Ho voluto pubblicare subito la quarta lezione di pesca sia per mantenere il ritmo di una a settimana, e tra la seconda e la terza ne ho saltate un paio, sia perché questa quarta lezione conclude la parte iniziale del corso, spiegando come completare la gestione della creazione, salvataggio, modifica, cancellazione della nostra prima classe, così da chiudere la prima parte per proseguire poi nelle prossime lezioni iniziando a parlare di ereditarietà.
Codice a corredo della quarta lezione
Tag di Technorati:
C#,
classi,
I/O,
ListView
lunedì 2 maggio 2011
#
Come promesso al workshop di Pordenone dello scorso 28 Aprile 2011, ho preparato il webcast del primo dei miei due interventi, quello relativo alla manipolazione di dati binari di grandi dimensioni su database SQL Server usando la scrittura e la lettura per Segmenti (Chunks).
In questo webcast composto da una parte spiegata su powerpoint e una seconda parte che mostra i punti principali del progetto demo a corredo, spieghiamo come fare a Scrivere su campi di tipo Image o di tipo VarBinary(max) suddividendo i dati binari in segmenti per poter gestire la memorizzazione di files di grandi dimensioni in un database.
Codice a corredo: sqlchunks.zip
sabato 30 aprile 2011
#
Nel terzo webcast della serie che ho chiamato “Non Solo Hello World”, proseguiamo lo sviluppo della nostra applicazione di test iniziando a vedere qualcosa di più sofisticato nella nostra classe dati di base e qualcosa di più sofisticato a livello di interfaccia.
Risponderemo con una prima versione alla domanda: “Ma come posso salvare dei dati digitati su schermo e persisterli su disco.”
E vedremo come realizzare una Form che inizi a fornirci i servizi di base per gestire una lista di oggetti su cui compiere le azioni classiche di Nuovo, Modifica, Visualizza.
Approfitto di questo post per ringraziare le oltre ottanta persone che hanno visualizzato i due webcast già pubblicati, consumando la pur generosa banda offerta dall’account gratuito di Screencast.com in pochissimo tempo. Ho già provveduto ad estendere l’account ad una versione Pro, per darvi modo di vedere i webcast senza limitazioni.
Grazie ancora e “Buona Pesca”.
Tag di Technorati:
C#,
classi,
I/O,
ListView
sabato 9 aprile 2011
#
Nel secondo webcast della serie dedicata allo sviluppo di una applicazione C#, rispondiamo ad un altro quesito frequente da parte di chi sta iniziando a lavorare in C#.
“Ma come faccio a passare dei dati da una form ad un altra e poi leggere le modifiche?”
Anche in questa seconda lezione, l’argomento ci serve per illustrare come iniziare a impostare una vera applicazione creando una ossatura visuale in cui cominciare a lavorare sui dati.
Se non vi fosse possibile vedere il video direttamente è disponibile a questo link Un po' piu' di hello World - lezione 2
Il codice sorgente a corredo
Technorati Tag:
Winforms,
C#,
forms
venerdì 1 aprile 2011
#
Il primo webcast non si scorda mai… 
Per il primo webcast, di quella che spero sarà una lunga serie, ho deciso di iniziare a dare una mano a quelli che iniziano, rispondendo ai quesiti che io per prima ho posto al mio insegnante, il primo era.
“Ma come faccio a crearmi delle librerie e poi chiamarle in un diverso progetto?”
Si tratta in realtà di una scusa per parlare di concetti di base OOP ed iniziare a costruire un progetto che nelle prossime lezioni si evolverà in una applicazione completa in grado di fare se pure in piccolo tutte le cose che una applicazione “reale” deve fare.
Vi prego di perdonare la rozzezza, ma sto ancora imparando ad usare lo strumento.
Se non vi fosse possibile vedere il video direttamente è disponibile a questo link Un Po' più di Hello World Lezione 1.
Il codice sorgente a corredo
Technorati Tag:
Winforms,
C#,
classi
martedì 29 marzo 2011
#
Non essendo qualcosa che si usa quotidianamente lo scrivo al solito per trovarlo se mi serve.
Un collega mi ha chiesto oggi di aiutarlo con un problema nella conversione di una funzione VB in C#, questa funzione calcola il checksum per una stringa rappresentante dei valori esadecimali che deve poi essere spedita ad una device via seriale.
Il problema era che VB converte “H&F6” in uno short , mentre short.TryParse( “0xF6”, out val) non lo fa.
Il problema è dovuto al fatto che per default TryParse si aspetta una stringa che contiene un numero e un esadecimale virtualmente non lo è.
La soluzione è usare la seguente riga di codice:
val = Int16.Parse("0xF6", System.Globalization.NumberStyles.HexNumber);
Molto facile, ma siccome ci ho perso mezz’ora a trovarla, spero di risparmiarla a qualcun’altro. 
lunedì 17 gennaio 2011
#
Oggi Stefano, ha fatto una domanda sul forum che sembrava molto semplice.
“Normalmente uso Screen.PrimaryScreen per catturare lo schermo da C# ma se ho più schermi collegati al pc come posso fare?”
La risposta era semplice, la classe screen ha una property AllScreens che è un array che ci da informazioni su tutti gli schermi connessi al PC, pertanto si può catturare semplicemente l’immagine di ogni schermo usando un ciclo for con il seguente codice:
Bitmap ps = new Bitmap(x.Bounds.Width, x.Bounds.Height);
Graphics graphics = Graphics.FromImage(ps as Image);
graphics.CopyFromScreen(x.Bounds.X, x.Bounds.Y, 0, 0, x.Bounds.Size);
ps.Save(string.Format(@"c:\MultiImage{0}.jpg", i), ImageFormat.Jpeg);
this.textBox1.Text += string.Format("DONE <{0}> ", i) + Environment.NewLine;
Ma quello che voleva Stefano, era comporre una singola immagine con lo schermo completo, lo stesso che si ottiene usando un printscreen (STAMP), e questo non è affatto semplice.
Infatti, ho fatto un test usando 2 schermi (lui ne ha 4) usando il mio notebook, Windows Vista e Seven, (XP non ricordo se lo facesse), quando colleghi uno schermo secondario, ti permettono di posizionarlo da che lato vuoi rispetto al primario, modificando di conseguenza le property che indicano dove si trova lo schermo secondario rispetto al primario.
A causa di ciò, comporre un’immagine non è così semplice e richiede qualche calcolo, (ovviamente si può anche usare la clipboard volendo, ma essendo qui per imparare C# e .Net ci proviamo in altro modo).
Ecco che cosa ho fatto:
int width = 0;
int height = 0;
int minx = 0;
int miny = 0;
for (int i = 0; i < Screen.AllScreens.Length; i++)
{
Screen z = Screen.AllScreens[i];
if (z.Bounds.X < minx) minx = z.Bounds.X;
if (z.Bounds.Y < miny) miny = z.Bounds.Y;
if (i == 0)
{
width = z.Bounds.Width;
height = z.Bounds.Height;
}
else
{
Screen p = Screen.AllScreens[i - 1];
//Sta a destra
if (z.Bounds.Right > p.Bounds.Right)
{
width += z.Bounds.Right - p.Bounds.Right;
}
else
{
//sta a sinistra
if (z.Bounds.Left < p.Bounds.Left)
{
width += Math.Abs(p.Bounds.Left - z.Bounds.Left);
}
}
//sta sopra
if (z.Bounds.Top < p.Bounds.Top)
{
height += (Math.Abs(z.Bounds.Top) - Math.Abs(z.Bounds.Bottom));
}
else
{
if (z.Bounds.Bottom > p.Bounds.Bottom)
{
height += z.Bounds.Bottom - p.Bounds.Bottom;
}
}
}
}
Basandomi sulla posizione dello schermo secondario, ho calcolato l’area dell’immagine composita e l’offset di posizionamento delle bitmap.
Bitmap ps = new Bitmap(width, height);
Graphics graphics = Graphics.FromImage(ps as Image);
this.textBox1.Text = "";
for (int i = 0; i < Screen.AllScreens.Length; i++)
{
Screen x = Screen.AllScreens[i];
this.textBox1.Text += string.Format("------------------->{0}<-------------------------", i)
+ Environment.NewLine;
this.textBox1.Text += "Top:" + x.Bounds.Top.ToString() + Environment.NewLine;
this.textBox1.Text += "Bottom:" + x.Bounds.Bottom.ToString() + Environment.NewLine;
this.textBox1.Text += "Left:" + x.Bounds.Left.ToString() + Environment.NewLine;
this.textBox1.Text += "Right:" + x.Bounds.Right.ToString() + Environment.NewLine;
this.textBox1.Text += "X:" + x.Bounds.X.ToString() + Environment.NewLine;
this.textBox1.Text += "Y:" + x.Bounds.Y.ToString() + Environment.NewLine;
this.textBox1.Text += "Width:" + x.Bounds.Width.ToString() + Environment.NewLine;
this.textBox1.Text += "Height:" + x.Bounds.Height.ToString() + Environment.NewLine;
this.textBox1.Text += string.Format("-------------------<{0}>-------------------------",
i) + Environment.NewLine;
graphics.CopyFromScreen(x.Bounds.X, x.Bounds.Y, x.Bounds.X + (Math.Abs(minx)),
x.Bounds.Y + Math.Abs(miny), x.Bounds.Size);
ps.Save(@"c:\SingleImage.jpg", ImageFormat.Jpeg);
this.textBox1.Text += string.Format("DONE <{0}> ", i) + Environment.NewLine;
}
Dopodiché compongo il bitmap sommando i due pezzi dello schermo. Sono certa c’è un modo migliore per farlo e ovviamente dovrete cambiare qualcosa per farlo funzionare con tre o più schermi. Se ci provate, fatemi sapere come avete risolto.
Technorati Tag:
C#,
capture screen
per scaricare il codice Loggarsi e andare in Area Risorse
giovedì 6 gennaio 2011
#
Non avevo avuto modo di leggere la posta personale dallo scorso venerdì, e stamattina, aprendo finalmente outlook, ho trovato due messaggi di Alessandro Teglia e … sono caduta dalla sedia …
, si trattava infatti della comunicazione dell’assegnazione dell’MVP Award. Così la befana (o la zia Yeye se preferite) è arrivata fra gli MVP. E’ ovviamente qualcosa che ti fa sentire come se camminassi a dieci centimetri da terra, non è cosa da tutti I giorni ricevere un riconoscimento della propria professionalità noto a livello planetario. A questo punto mi verrebbe voglia di scrivere dei ringraziamenti da Oscar, ma credo sia ridicolo, pertanto ringrazio I responsabili del programma MVP di Microsoft per aver dato credito ai miei 23 anni di lavoro con tecnologie Microsoft, un lavoro che trovo appassionante ora come il primo giorno davanti ad un PC XT IBM, provando come funzionavano I comandi DOS seguendo il manuale operativo di base.
giovedì 30 dicembre 2010
#
Una minuscola applicazione ispirata da una richiesta di Stefano Pranzo, per creare un applicazione che visualizza il conto alla rovescia per la fine dell’anno.
Il risultato finale è questo, per ottenerlo creiamo una nuova applicazione Windows Forms, Rinominiamo Form1 FrmCountDown, e cambiamo le seguenti property:
- BackgroundImage –> Scegliamo una immagine cliccando sul bottone con i 3 puntini ed importiamola nelle resources di programma, quella che vedete l’ho trovata su bing digitando newyear nella ricerca immagini.
- BackgroundImageLayout –> Stretch
- FormBorderStyle –> None
- KeyPreview –> True (questa ci serve per gestire il quit).
Aggiungiamo alla form una label che chiamiamo lblCountdown e a cui diamo le seguenti proprietà:
- BackColor –> transparent
- Font Name –> Lucida Calligraphy
- Font Size –> 64
- Forecolor –> Gold
- TextAlign –> MiddleCenter
Aggiungiamo alla form un button che chiamiamo btnClose e a cui diamo le seguenti proprietà:
- UseVisualStyleBackColor –> False
- FlatStyle –> Flat
- BackColor –> transparent
- Font Name –> Lucida Calligraphy
- Forecolor –> Gold
- Text –> Close
Aggiungiamo alla form un timer che chiamiamo tmrCountdown.
Implementiamo il codice dietro alla form:
public FrmCountDown()
{
InitializeComponent();
tmrCountdown.Interval = 1000;
tmrCountdown.Enabled = false;
}
Nel costruttore settiamo l’intervallo del timer a 1 secondo (1000 millisecondi) e lo disattiviamo.
private void FrmCountDown_Load(object sender, EventArgs e)
{
tmrCountdown.Start();
}
Sull’evento Load della form attiviamo il timer.
private void btnClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
Sull’evento click del bottone Close implementiamo la chiusura applicazione.
private void FrmCountDown_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
Application.Exit();
}
}
Sulla pressione del tasto Esc della tastiera facciamo lo stesso.
DateTime mDtEnd = new DateTime(2011, 01, 01, 0, 0, 0);
Creiamo una variabile a livello di form che contiene la data finale del conto alla rovescia, quindi le 00:00:00 del primo gennaio.
private void tmrCountdown_Tick(object sender, EventArgs e)
{
TimeSpan sp = mDtEnd.Subtract(DateTime.Now);
this.lblCountdown.Text = sp.TotalHours.ToString("###") + ":" +
sp.Minutes.ToString("0#") + ":" + sp.Seconds.ToString("0#");
Application.DoEvents();
}
Infine, sull’evento Tick del timer andiamo ad aggiornare la nostra label facendo una differenza fra la data attuale e la data finale e convertendo il dato in una stringa formattata. Come potete vedere abbiamo usato il metodo Subtract della classe DateTime e le property TotalHours, Minutes e Seconds del Timespan che rappresenta la differenza.
Ed il nostro countdown di fine anno è pronto.
Il codice sorgente completo lo trovate in area risorse.