martedì 2 ottobre 2012
Ieri ho ricevuto la nomina di Microsoft Valuable Professional per il decimo anno consecutivo.
Chissà perché le cifre tonde fanno tanta impressione, potrei pensare che in fondo 10 anni sono solo 1 anno di più di 9 ma per qualche motivo le emozioni di questa nomina sono un po' più speciali.
L'anno scorso ho tenuto due dozzine di speech, post su vari forum, articoli technet/msdn e un numero di progetti con diversi team di Redmond, cose che conto solo quando mi vengono richieste e che quando le conto mi fanno girare la testa perché il tempo già lo impiego per altre mille. Mentre le faccio non pesano più di tanto e questo mi rincuora sul fatto che sia solo la passione a guidarmi, da sempre, da quando ho iniziato con il caro vecchio ZX81. Ho la gran fortuna di fare il lavoro che ho voluto e che mi piace più di qualunque altro.
Beh allora grazie Microsoft perché non prende e basta ma ringrazia e incassa pure le critiche quando ci vogliono (non tutti in Microsoft accettano le critiche ma peggio per loro).
Un grazie sincero anche a tutti coloro che mi supportano, gli amici delle communities. Il loro affetto è il vero carburante di questa pazzo modo di vivere.
giovedì 16 agosto 2012
Ieri, il 15 di Agosto è stata rilasciata la prima drop pubblica di Windows 8 RTM, i bit finali, per gli abbonati MSDN e Technet. È anche disponibile una versione demo da 90 giorni che potrà essere aggiornata (semplicemente mettendo la key di attivazione) a partire dal 26 Ottobre, data della disponibilità nei negozi.
Link Demo Windows 8 Enterprise: http://msdn.microsoft.com/en-us/evalcenter/jj554510.aspx
Comparazione delle versioni di Windows 8 (vedere tabella): http://en.wikipedia.org/wiki/Windows_8_editions
Da notare che la Enterprise non può essere usata per aggiornare un Windows 7 mantenendo le impostazioni e le applicazioni esistenti. Per gli aggiornamenti ci vuole la Pro.
Vado a riassumere brevemente gli step di due installazioni che ho concluso ieri sera: una installazione da zero e un upgrade di Windows 7.
Installazione 'fresca':
La prima cosa che ho fatto è di salvare tutto il contenuto dell'hard disk in un immagine. Allo scopo ho usato un tool nuovo nuovo di Paragon che è gratuito e che supporta già anche Windows 8 e Windows server 2012 (che ha un nuovo file system chiamato Re-Fs).
Link al tool: http://www.paragon-software.com/technologies/components/image-backup-windows-8/index.html
Il secondo step è stato quello di scaricare l'immagine di Windows 8 in formato ISO. Per questa installazione 'clean' ho scelto la versione Enterprise.
Si può masterizzare un DVD o, meglio, creare una chiavetta USB bootable grazie a questo tool: http://www.microsoftstore.com/store/msstore/html/pbPage.Help_Win7_usbdvd_dwnTool
Il suo funzionamento è semplice: scelgo la ISO, indico la chiavetta USB su cui installarla e il tool formatta la chiavetta rendendola bootable con quell'immagine.
Il terzo step è ovviamente l'installazione. Inserisco la chiavetta USB e faccio il boot. Tipicamente al bios scelgo F8 per i PC desktop o F12 per i portatili in modo da ottenere il menu di boot del bios. Una volta fatto il boot dalla chiavetta USB, installo scegliendo l'opzione "Custom" e non "Upgrade". In questo modo posso cancellare tutti i dati dall'hard disk (abbiamo fatto il backup prima) e procedere all'installazione.
Per attivare la versione enterpise bisogna avere la key "MAK" (Multi Activation Key) che si installa con:
slmgr /ipk <key mak>
Attenzione che la command line per le versioni precedenti era "slmgr –ipk" ma il trattino per qualche motivo è stato cambiato.
Installazione 'upgrade di Windows 7':
Per questa operazione, come dicevo prima, è necessario usare la versione Windows 8 Pro (non ho fatto esperimenti sulla versione base, la "Windows 8").
Ovviamente serve la ISO (e la key di attivazione) che deve essere compatibile per numero di bit (x86 o x64) con quella di aggiornamento.
Per montare la ISO come drive locale si può usare un tool come Virtual CloneDrive: http://www.slysoft.com/it/virtual-clonedrive.html
Da notare che Windows 8 esegue il mount delle ISO, per cui il tool serve solo durante la fase di aggiornamento.
Molto probabilmente vorrete fare un backup del disco prima di procedere. Io ho preferito clonare il disco interamente e installare sul nuovo. Per comodità ho comprato un nuovo disco SSD e ho clonato il vecchio (più piccolo di dimensione) sul nuovo. La dimensione maggiore semplifica l'operazione di cloning.
Per clonare il disco ho usato Clonezilla (http://clonezilla.org/) un tool Linux che si installa su una chiavetta USB su cui fare il boot (la preparazione della chiavetta è semplice, basta seguire le istruzioni del sito).
Quindi shutdown, collegati i due dischi e nulla di più per non rischiare, boot con Clonezilla e via alla copia facendo molta attenzione a scegliere la copia nel verso giusto.
Una volta clonato il disco, si fa reboot (ancora in Windows 7 ovviamente) ma con il nuovo disco e tutto fila (deve filare) liscio. Usando Computer Management si potrà notare che una parte di disco non viene utilizzata in quanto il disco di destinazione è più grosso.
Per ingrandire la partizione si procede con diskpart (http://support.microsoft.com/kb/325590/it)
command prompt amministrativa, digitare diskpart
- list disk per vedere le unità
- select disk <numero> per selezionare il disco di cui si vuole ingrandire la partizione
- list partition per vedere le partizioni del disco (normalmente sono 2)
- select partition <numero> per selezionare la partizione da ingrandire (tipicamente quella più grossa)
- Digitare extend per estendere la partizione e il gioco è fatto.
Dopo un reboot di sicurezza (nel frattempo dovrebbero essere stati installati i driver del nuovo hard disk) si parte con l'upgrade
Eseguito il mount della ISO, via al setup che mostrera, nel caso, le applicazioni non compatibili da disinstallare prima di procedere.
Non è obbligatorio ma è consigliabile. Io ho perso CheckPoint VPN (che è fatto già male di suo) e penso di reinstallare in una VM Windows 7.
Al reboot, se necessario, l'upgrade continua. Attenzione alla scelta se si vuole mantenere applicazioni e dati o solo dati.
Finito l'upgrade mi ha funzionato tutto alla perfezione e con il dual monitor è uno spettacolo.
Visual Studio 2012 RTM che ho installato su Windows 7 prima dell'upgrade ha funzionato benissimo e il wizard ha aggiunto automaticamente la possibilità di creare applicazioni WinRT che ovviamente su Windows 7 non erano disponibili.
Considerazioni di Windows 8 come sistema operativo desktop
In questi mesi se ne sono sentite di tutti i colori sull'usabilità di Windows 8 sui PC … quante occasioni di stare un po' più zitti… provare prima di parlare.
Se già sul notebook mi trovavo benone, le prime impressioni su un vero pc desktop con dual screen e montagne di cose installate è ottima:
- Il menu di start come tutti sanno è full screen … e questo è decisamente comodo anche perchè posso riarrangiare l'ordine delle tile/icone che mi servono più spesso.
- Le applicazioni su cui lavoro quotidianamente funzionano ed esattamente come prima.
- Effetto glass … perso, è solo una questione estetica che personalmente è secondaria. Non ho neppure guardato se sia tweakabile, non mi interessa affatto.
- Virtualizzazione. Adesso è abilitabile il ruolo HyperV che permette la gestione di macchine virtuali con hypervisor, e quindi fornendo un livello di prestazioni molto diverso dalla classica virtualizzazione desktop. Se usavate altre soluzioni di virtualizzazione dovrete scegliere il da farsi. Dubito che possano coesistere.
- Le applicazioni WinRT girano full screen. Sono applicazioni che prima non c'erano quindi mi sta anche bene. Personalmente avrei preferito una sorta di "virtualizzazione" di queste applicazioni in modo che potessero girare in una finestra isolata e non full-screen. Questo avrebbe permesso di far girare più ambienti WinRT in contemporanea e quindi visibili allo stesso tempo…. chissà se ci faranno un pensiero.
Il resto delle features di Windows 8 è tutto in più e chi lo vuole usare bene, altrimenti non fa certo danno.
Un consiglio ai detrattori: non installatelo, questo post è rivolto solo a coloro che hanno voglia di andare avanti.
lunedì 25 giugno 2012
La buona notizia per noi è che la mia azienda ha ottenuto il Token per la pubblicazione di applicazioni Metro-Style sullo store di Windows 8. Attualmente lo Store è ancora chiuso al pubblico a meno che non venga sostenuta una sorta di pre-certificazione.
Mentre stavamo lavorando ad una applicazione di Barcode abbiamo incontrato un'eccezione randomica di tipo 0xC000027B che non ha una storia utile in internet, nè è disponibile una descrizione dell'errore che possa suggerire qualcosa.
Cosa dovrebbe fare in questo caso lo sviluppatore? La normale procedura diagnostica è la seguente:
- Dalle proprietà del progetto, opzioni Debug, abilitare il "Mixed Mode Debugging". Poiché WinRT e Xaml sono dll native (C++) molti dettagli verrebbero nascosti in assenza dell'abilitazione del debugger nativo.
- Riprodurre il problema con questi settaggi guardando la "Output Window" in Visual Studio. Quando il debugger nativo/mixed è abilitato potrebbero vedersi più messaggi nella finestra di output.
- Tenere d'occhio la "Call Stack Window". Se si vede una chiamata del proprio codice dentro lo stack trace, significa avere un buon punto di partenza per capire le cause del problema. Diversamente può essere un problema che si verifica nel loop di rendering, all'interno del thread del dispatcher. In questo caso si vedranno solo liberie Microsoft come la Windows.UI.Xaml.dll.
- Se si vuole capire cosa stiano facendo le librerie WinRT/Xaml libraries were doing, ovviamente il codice assembler non può essere di aiuto, ma abbiamo ancora un'arma a nostra disposizione. Nella finestra di Visual Studio accessibile da Tools – Options – Debugging – Symbols, abilitare i Microsoft Symbol Servers. Si può usare anche la "Modules Window" per verificare che siano caricati i simboli relativi alle dll usate dall'applicazione.
- I simboli pubblici daranno un nome di metodo/funzione al codice assember. Non si vedranno i sorgenti ma il nome del metodo può rivelarsi decisamente molto utile.
Ma torniamo al problema che abbiamo riscontrato. La procedura appena descritta non ha aiutato affatto poiché non c'erano simboli pubblici disponibili per Windows.UI.Xaml.dll e l'eccezione era generata da quella dll.
Abbiamo così applicato il vecchio trucco di copiare il progetto in un altra cartella e cancellare tutte le parti della UI fino a che il problema non si verificava più. Si, è un pessimo modo di inseguire un bug ma era anche l'unica possibilità.
E ha funzionato alla grande, scoprendo così che la causa del problema era il tag <Image … /> dentro la Grid usata per eseguire il layout della pagina. Navigando avanti e indietro su questa pagina veniva generata l'eccezione dopo circa 10-20 navigazioni. Abbiamo anche scoperto che ci sono più variabili che cambiano le condizioni del bug, come le transitions e i controlli usati nella pagina verso cui si navigava e persino dal modo in cui viene utilizzato il mouse. Un misto di stregoneria e incantesimi .
La soluzione è super-semplice: basta mettere un <Border /> intorno ad ogni singola immagine nell'applicazione… e l'eccezione scompare!
domenica 27 maggio 2012
Ad un paio d'anni dal lancio di Visual Studio 2010, torno in Romania per una bellissima iniziativa community che si svolgerà nei giorni di 28 e 29 maggio (a partire da domani) a Cluj-Napoca, seconda più popolosa città della Romania, capitale non-ufficiale della regione della Transilvania.
Naturalmente la mia sessione riguarderà WinRTe lo sviluppo di applicazioni Metro per Windows 8.
Un ringraziamento particolare va agli organizzatori dell'evento Tudor Damina e Mihai Tătăran.
giovedì 26 gennaio 2012
I giorni 28 e 29 Marzo, Microsoft Bulgaria terrà il tradizionale evento "Microsoft Days".
È con molto piacere che annuncio di essere speaker per due argomenti di grande rilievo per la prossima ondata di tecnologie:
Gli abstract sono pubblicati qui:
http://www.msbgregistration.com/Presenter.aspx?PresenterId=257
A presto Sofia!!!
lunedì 23 gennaio 2012
Sono trascorsi 10 anni da quando Bill Gates spedì a tutta Microsoft una famosa email nella quale affermava la necessità di un cambio di approccio nel confronto della sicurezza applicativa.
Da allora sono successe tante cose e senza dubbio sono stati raggiunti traguardi importanti non solo riguardanti i prodotti Microsoft ma anche nelle librerie, nei tool e soprattutto nella metodologia che aiuta noi sviluppatori a rendere il nostro codice più sicuro.
Ho avuto il grande privilegio ed onore di scrivere l'articolo commemorativo per la Technet Security Newsletter che è presente pubblicato a questo link: http://technet.microsoft.com/en-us/security/hh778965.aspx
Poiché quei link puntano alle newsletter del mese corrente, riporto qui di seguito lo screenshot della pagina:
Grazie Microsoft per la bella opportunità.
venerdì 18 novembre 2011
In qualità di membro del "Developer Guidance Council" qualche tempo fa sono stato coinvolto per la revisione di un tutorial sul deploy di applicazioni Asp.net che è stato appena pubblicato a questo indirizzo:
http://www.asp.net/visual-studio-2010/tutorials/deploying-with-visual-studio-2010
http://www.asp.net/web-forms/tutorials/deployment-to-a-hosting-provider
Il tutorial è interessante perché rappresenta degli scenari reali, classici ed analizza passo per passo le best-practices e i potenziali problemi in vista della pubblicazione.
Chi è già esperto sull'argomento non troverà nulla di nuovo ma rimane comunque una valida risorsa che riassume i punti fondamentali.
Ringrazio infine il team per il gradito riconoscimento della review e delle lunghe discussioni che riporto in questo screeenshot:
Update del 6 Dicembre 2011: grazie a Fabrizio Camera per l'aggiornamento del link.
lunedì 24 ottobre 2011
La nuova schermata di start di Windows 8 mostra una serie di "tile" che potrebbero sembrare una versione rinnovata dei vecchi shortcut:
Ma l'apparenza inganna e i tile non sono shortcut e non lanciano direttamente il processo dell'applicazione.
Il punto cruciale è che Windows Runtime (WinRT) è lo strato del sistema operativo che permette un dialogo object oriented tra applicazione e altre applicazioni o sistema operativo. In un ambiente object oriented il dialogo avviene ovviamente tramite interfacce.
WinRT, al contrario di COM, stabilisce delle interfacce standard che permettono il dialogo con le applicazioni. Sto parlando dei Contracts di Metro.
Quando viene fatto "tap"/"click" su un tile, Explorer.exe utilizza il contratto di "Launch" che ogni applicazione Metro creata da Visual Studio implementa automaticamente.
Per ogni contratto Explorer conosce la lista delle applicazioni che lo implementano semplicemente cercando nel registry (HKEY_CURRENT_USER\Software\Classes\Extensions cioè il ramo per-utente e non per-machine).
Per quanto ho potuto capire, le interfacce del contratto di Launch sono Windows.UI.Xaml.IApplication e Windows.UI.Xaml.IApplicationOverrides che sono implementate dalla classe "Windows.UI.Xaml.Application" da cui deriva per esempio la classe "App" di un progetto C# Metro. Al momento però MSDN non fornisce alcun dettaglio su queste interfacce che hanno visibilità "private".
Oltre al "tap"/"click" una applicazione può essere attivata a seguito di altri contratti come per esempio Search o Share. Per esempio la nostra applicazione potrebbe candidarsi a fornire l'elenco dei file in formato custom che contengono una certa parola chiave.
Quando l'utente utilizza il "search charm" di Windows per cercare la parola "Raf", Explorer mostra l'elenco delle applicazioni che si sono candidate al contratto di Search. A questo punto l'utente sceglie una applicazione e questa viene attivata allo scopo di eseguire la ricerca. È importante notare che l'applicazione può essere attivata più volte, una per ciascun contratto, nel qual caso ogni attivazione viene servita nello stesso processo ma in thread differenti.
Il contratto di Share è del tutto analogo: viene mostrato l'elenco di applicazioni che possono condividere un elemento e una volta che l'utente ha scelto l'applicazione con cui condividere quell'elemento, questa viene attivata.
L'attivazione
Il punto cruciale si sposta quindi sull'attivazione dell'applicazione. Prendiamo in esame il contratto di Launch che attiva l'applicazione a seguito del "tap"/"click" in Explorer.
Explorer mostra sullo Start Screen tutte le applicazioni i cui package sono registrati nel sistema sottoscrivendo il contratto di Launch. Appena l'utente ne richiede il lancio ("tap"/"click") Explorer utilizza le informazioni del registry appena mostrate per iniziare l'attivazione a cura di due oggetti WinRT usati internamente da Windows: Extension Catalog ed Extension Registration che si avvalgono della persistenza del registry (Extension Catalog e Class Catalog).
Explorer si avvale di RPCSS, il servizio di sistema RPC, per attivare l'applicazione. Poiché RPCSS è esposto alla rete ed ha una vasta superficie di attacco, RPCSS gira con privilegi molto bassi (network_service) e con un integrity level system che impedisce ad altri processi con integrity level più basso di poter agire su RPCSS in lettura o scrittura.
Come è stato detto durante build conference, RPCSS mantiene la lista degli oggetti attivati, ed è in grado di crearne un pool (qualcuno ricorda COM+?) tramite IObjectControl.
Per avviare il processo (surrogato o reale), RPCSS si avvale del servizio "DCOM Launcher" che ha privilegi più elevati (localsystem). Il servizio "DCOM Launcher" rilegge dal registry le informazioni relative alla classe ed al processo host ed esegue il processo dell'applicazione.
Una volta in memoria il processo della nostra applicazione esegue una serie di operazioni:
- inizializza il thread corrente come MTA (Multi Threading Apartment) che consente di gestire richieste COM in modo concorrente
- crea il "Core Application Object" (Windows.ApplicationModel.Core.CoreApplication)
- invoca il metodo Run sul "Core Application Object" (che ha per parametro IViewProviderFactory, la factory che serve a creare la view della nostra applicazione)
- il metodo Run registra il "Core Application Object" presso RPCSS che a sua volta lo restituisce all'Extension Registration Object di Windows Explorer
Questo è il punto cruciale perché da questo momento in poi è possibile "parlare" con il nostro processo utilizzando il pattern ABI (Abstract Binary Interface). Niente più chiamate ad API "C-like" ma un dialogo a runtime interamente object oriented.
COM si fondava sugli stessi concetti ma ci sono differenze importanti e non solo per quanto riguarda il type system o l'asincronicità ma in prima istanza per il contratto di attivazione. Il meccanismo che ho appena descritto permette l'attivazione di una generica applicazione mentre DCOM non stabiliva una ricca ABI per parlare con una generica applicazione.
Più che applicazioni, questi processi sono dei pseudo-COM Server in cui il dialogo avviene via ABI, in cui la nostra applicazione è anch'esso un oggetto WinRT.
Il sistema di attivazione di Explorer esegue poi una chiamata cross-process verso il "Core Application Object" della nostra applicazione che riceverà le notifiche sulle richieste di attivazione, suspend, resume e termine.
Per ogni richiesta di attivazione (che può essere una per ogni contratto WinRT di cui l'applicazione è provider) viene creato un nuovo thread in modalità STA (Single Threaded Apartment) dove girerà il nostro codice relativo alla gestione della finestra, della ricerca, dello share, etc..
STA significa che tutte le chiamate eseguite dall'esterno al nostro codice saranno accodate e perciò non dovremo prendere nessuna precauzione per eventuali chiamate concorrenti (fermo restando che se noi internamente utilizziamo chiamate asincrone il problema andrà gestito come abbiamo sempre fatto).
Tool
Come fare per debuggare/capire il meccanismo di attivazione? La sessione di Matt è il miglior punto di partenza. Nella sessione Matt usa un tool che non è disponibile, ma grazie alle sue indicazioni ho riscritto un nuovo tool che ho pubblicato su http://winrt.codeplex.com (compresi i sorgenti) ed aggiunge alcune utili funzionalità che vado a riassumere qui:
- Mostra la lista di tutti i package del sistema
- Permette di lanciare l'applicazione con il debugger attached.
- Forza il suspend/resume di una applicazione
- Termina i processi che fanno l'host della nostra applicazione
Nella pagina del progetto di Codeplex sono presenti anche una serie di esempi delle command line.
Il tool è quindi utile anche per chi non voglia fare deep diving degli internals di WinRT ma voglia triggerare suspend/resume o terminare l'applicazione.
Conclusione
L'attivazione è il processo che meglio rappresenta la potenza di WinRT e la reale innovazione di Windows 8. Non si possono "liquidare" le applicazioni Metro come una mera piattaforma che permette di lanciare applicazioni web sul client. WinRT non è un "PhoneGap" firmato Microsoft.
Il Framework.NET ha aperto la strada dell'interoperabilità tra linguaggi permettendo un grado di libertà molto ampio agli sviluppatori. WinRT prosegue questa apertura permettendo un efficiente mix di linguaggi nativi/managed/scripting indispensabile per sfruttare pienamente le funzionalità di basso livello del sistema operativo.
Con Windows 7 Microsoft creò Windows API Codepack per interoperare tra i linguaggi managed ed il sistema operativo. Grazie a WinRT questi wrapper diverranno presto inutili e l'interoperabilità molto più facile e performante.
Ci sono ancora tante cose da vedere come le chiamate asincrone e la security… stay tuned!
martedì 18 ottobre 2011
Visto che il mondo WinRT è un'evoluzione di quello COM, anche la registrazione è simile ma utilizza solo le chiavi di registro HKCU per cui non è necessario avere privilegi amministrativi.
Vediamo le chiavi di registry più interessanti:
La chiave HKCU\Software\Classes\ActivatableClasses\Package contiene la lista dei package registrati nel sistema.
Ogni sottochiave ha per nome il "Full Package Name" che è impostabile da Visual Studio 11 aprendo il file del manifest:
Di default il "Package name" è un guid ma è più conveniente utilizzare un nome completo di namespace e nome applicazione. Nel caso della app demo in javascript, ho impostato il nome a "IAmRaf.DemoApp" che troverò nel registry con alcune informazioni supplementari:
Sotto la chiave ActivatableClassId troviamo il nome della classe che si prende carico di "attivare" l'applicazione. Lo possiamo considerare il nostro punto di ingresso object oriented:
- "ActivationType" specifica se il componente è attivabile in-process (0) oppure out-of-process (1).
- "Server" specifica il nome della chiave Server sottostante (App.wwa)
Come da figura, App.wwa è il nome di default che è impostabile (solo via XML) nel manifest mentre "name" del tag "identity" è il "Package name" già modificato precedentemente.
Nel registry perciò possiamo vedere questi valori:
Sotto la chiave Server troviamo lo stesso "App.wwa" specificato sopra, dentro il quale troviamo la path completa all'exe del processo che fungerà da host.
- Se realizziamo l'applicazione in C#/VB/C++ questo corrisponde all'exe che abbiamo generato da Visual Studio
- Se invece è una applicazione javascript, questo specificherà un exe surrogato (analogo a dllhost dei tempi di COM)
Come si può vedere in figura l'host per l'applicazione di esempio è WWAHost.exe che è il generico host di una applicazione html5/javascript.
Il processo surrogato è importante per quei linguaggi che non possono provvedere al classico metodo "main". I progetti Metro realizzati con C# forniscono automaticamente il metodo main che istanzia la classe "App" (Xaml) e chiama il metodo statico Run. Applicazioni che utilizzano javascript necessitano un processo surrogato (WWAHost.exe) che sappia come renderizzare html5 e gestire gli script javascript. Explorer passa a WWAHost.exe l'application id (App.wwa nel nostro caso)via command line.
Il punto di ingresso dell'applicazione si trova sotto la chiave CustomAttributes. Le due immagini mostrano la differenza tra l'entry-point della demo in javascript e un'altra in C#:
Dalle ricerche che ho fatto, sembra possibile creare una applicazione o provider di un contratto come dll in-process. In questo caso non esisterebbe la "main" e di conseguenza l'entry-point sarebbe fondamentale.
Il processo di registrazione non è interessante per lo sviluppo di applicazioni ma può essere fondamentale per motivi diagnostici e per capire il valore degli elementi del manifest.
Nel prossimo post vedremo i passi essenziali all'attivazione dell'applicazione.
giovedì 13 ottobre 2011
Durante la build conference, oltre a sessioni entusiasmanti come quella di Matt, ho avuto modo di farmi spiegare molti dettagli interessanti su WinRT. Grazie quindi agli speaker e altri membri del team per la loro disponibilità alle numerosissime domande di tutti i presenti. Questa è una lavagna emblematica:
Per quanto mi riguarda, è stato illuminante il paragone con COM e il nuovo meccanismo di attivazione che ripercorrerò rapidamente in questi post.
Dopo aver creato una applicazione Metro, Visual Studio 11 permette di generare il file del package che è la nuova unità di deploy per le applicazioni Metro-Style.
Visual Studio permette di creare un package tramite il menu "Project – Store – Create App Package". A seguito di questo comando il wizard esegue una serie di operazioni:
- embedding di manifest, metadati, risorse e altri eventuali file necessari al progetto (dll, etc.)
- generazione del package (un file zip)
- firma del package con un certificato
Il package generato costituisce l'unità di deploy e non ha altre dipendenze, fatta eccezione per il Framework.NET (solo se viene utilizzato un linguaggio managed) oppure i file VC++ runtime (solo se si utilizza C++). La nuova applicazione avrà comunque la necessità di WinRT che è/sarà disponibile solo su Windows 8.
Il package di fatto elimina la necessità di creare un package MSI ma l'installer msiexec è tutt'altro che morto visto che è proprio lui ad eseguire la registrazione del certificato, installare il package e registrare l'applicazione nel registry.
L'installazione può essere fatta ad opera di Visual Studio (anche senza creare il package prima), del Windows Store (quando sarà disponibile) oppure di un batch generato da Visual Studio e che utilizza powershell. Questo batch necessita dei diritti di amministratore per poter installare il certificato self-signed, cosa che non avviene nel caso di installazione dallo Store/Marketplace di Windows.
Il package viene registrato nel sistema nella porzione di registry dell'utente corrente (HKCU) e questo significa che un utente è in grado di installare applicazioni Metro senza necessità di diritti amministrativi.
All'interno del package ci sono le eventuali dll che definiscono "componenti WinRT" (classi WinRT che espongono type che fanno parte del type system WinRT) o "controlli WinRT" (come i componenti WinRT ma che definiscono un nuovo controllo Xaml). Questi sono sempre privati e di conseguenza:
- non necessitano di registrazione globale come avveniva in COM o GAC per il Framework.NET
- non essendo globale, non esiste il problema del versioning. Ogni applicazione può utilizzare versioni differenti dello stesso componente WinRT
Per gestire i package delle applicazioni Metro ci sono dei cmdlets dedicati, ben riassunti qui, che vado ad elencare:
- Powershell in un prompt dei comandi per entrare in modalità Powershell ed "exit" per ritornare al prompt dei comandi.
- get-help appx restituisce la lista dei cmdlet specifici dei package
- get-appxpackage restituisce la lista dei package installati nel sistema
- add-appxpackage file.appx installa un package nel sistema
- remove-appxpackage packagefullname rimuove il package (specificare il nome del package ottenuto con get-appxpackage)
Fare riferimento al link sopra citato per alcuni comodi trucchi specifici di powershell.
Nel prossimo post vedremo i passi essenziali della registrazione del package.
martedì 4 ottobre 2011
Sto postando con qualche giorno di ritardo (1 Ottobre) la fantastica notizia ricevuta da Microsoft: il rinnovo per il nono anno consecutivo al premio MVP per la categoria Developer Security.
Ho già festeggiato con tanti amici su Twitter e Facebook ma non potevo mancare di lasciare una traccia anche sul mio blog ringraziando Alessandro e tutto il team MVP di Redmond per questo fantastico riconoscimento.
La cosa che apprezzo di più del programma MVP è che c'è un reale connubio tra due concetti: il rapporto confidenziale tra Microsoft e gli MVP e l'indipendenza che questi hanno nei confronti di Microsoft. Il motto MVP è infatti "Independent Experts. Real World Answers".
Ho sempre potuto esprimere le mie opinioni in modo libero, dagli entusiasmi più sfrenati per le tante tecnologie a cui mi sono appassionato alle critiche molto ferme per alcune scelte fatte su certi prodotti. Questo non ha influenzato il rapporto con Redmond e dimostra il vero pieno valore del programma MVP. Di questo non posso che ringraziare perché è realmente un valore insostituibile.
giovedì 29 settembre 2011
Nel precedente post ho ripercorso le motivazioni che hanno portato a WinRT.
Uno dei requisiti fondamentali di WinRT è di permettere una migliore interazione tra linguaggi differenti, sia nativi che managed. Abbiamo anche già visto che per avere un'interoperabilità pulita e semplice sia necessario un vero e proprio runtime che esponga le funzionalità in modo object oriented.
L'interoperabilità tra i linguaggi e WinRT viene appianata dalle "projections" che risolvono due problemi:
- Usare WinRT dai linguaggi in modo semplice e performante
- rendere WinRT disponibile ai linguaggi come fosse una libreria di quel linguaggio e quindi utilizzabile in modo "naturale"
Il primo passo è stato perciò quello di stabilire un type system.
I tipi numerici sono supportati nelle versioni con e senza segno (interi e floating point). Il problema maggiore nasce per javascript che, stando alle specifiche ECMA, supporta un solo tipo numerico (il tipo floating point delle specifiche IEEE-754) sia per interi che per float, cosa che gli impedisce di gestire gli interi oltre i 53 bit di precisione. Il kernel di Windows usa i tipi a 64 bit (anche nella versione a 32 bit) per certe funzionalità come la dimensione dei file, gli offset, etc.
Esiste un nuovo tipo String la cui rappresentazione binaria permette di evitare il marshalling con le wstring di C++ o del Framework.NET. La nuova String è immutabile come nel Framework.NET ma invece di essere un reference type in WinRT è un value type come accade per wstring e quindi non-nullabile. Questo permette di appianare la differenza tra i vari linguaggi. Per costruire stringhe i developer C++ useranno wstring o wstringstream, mentre quelli VB/C# useranno come sempre StringBuilder.
Reference type. WinRT descrive il layout degli oggetti usando le interfacce, conseguentemente sono reference type tutti gli oggetti che implementano interfacce. Perciò durante una chiamata i parametri che sono oggetti sono passati by reference mentre tutto il resto sono by value. Inoltre i parametri sono passati come [in] o [out] e mai in [in, out].
Value type. Rispetto alla definizione dei reference type, i value type sono "il resto". Gli array sono value type (al contrario del Framework.NET) e le structure che non possono contenere puntatori/reference eliminando così il problema del costo e di come implementare la copia (deep vs shallow copy).
Tra i vari type definiti nel namespace "Platform" spiccano Vector e Map, analoghi a collection e dictionary del Framework.NET. Da notare che Vector<T> è implementa IObservableVector<T> e quindi supporta nativamente le notifiche sulle modifiche.
Ovviamente ci sono boolean, enum e molti altri tipi di base come Object, Type e Guid, ma su cui non ho trovato nulla di diverso da ciò che mi attendevo.
Per rendere disponibile WinRT ai linguaggi in modo naturale, le projection modificano anche il casing della libreria. Le convenzioni di javascript per esempio sono di usare camelCase per properietà e metodi, il PascalCase per i type e lowercase per gli eventi. WinRT invece segue sempre le convenzioni del Framework.NET, cioè il PascalCase. La projection modifica i nomi delle librerie seguendo le convenzioni del linguaggio "projected".
È chiaro che ogni linguaggio presenta comunque particolarità che non possono essere ignorate. Questo è stato un problema anche durante il design del Framework.NET (vedi attributo CLSCompliant) e continua ad esserlo in WinRT.
Piuttosto il fatto di aver definito il modo in cui i linguaggi sono interfacciati a WinRT apre l'interessantissimo scenario dei linguaggi di terze parti. A questo punto sembra un passo ovvio per Java, Python, Ruby, D, Delphi e chissà quanti altri.
mercoledì 21 settembre 2011
Il lavoro di DotNetLiguria è frenetico! Il nostro board non si è mai fermato e così siamo già giunti al terzo appuntamento che si terrà il 30 Settembre prossimo.
Prima novità: una nuova sala a Sestri Ponente, gentilmente offerta da VirtuSestri, che ha il doppio di capacità rispetto alla precedente.
Seconda novità: inizio alle ore 17:00 con una roundtable. In molti ci hanno dato il feedback di essere disposti a partecipare ad eventi di mezza giornata, cosa che ci ha piacevolmente sorpreso. Così vogliamo iniziare a vedere come vanno le cose partendo dalle ore 17:00. Questo primo slot sarà una discussione aperta tra tutti i partecipanti in merito a quanto è stato presentato alla //build/ conference. Naturalmente mi faccio carico di tutte quelle piccole notizie di cui si legge poco ma che ho vissuto in prima persona ad Anaheim.
Seguirà la mia sessione di introduzione a WinRT.
Terza novità: tre slot. Non vogliamo essere troppo futuristici e siamo convinti che la sessione di Alessandro Gambaro dedicata ad IoC sia il pezzo forte e di immediata applicabilità nello sviluppo di tutti i giorni.
Le iscrizioni sono aperte: http://www.dotnetliguria.net/
Essendo i posti limitati si raccomanda di annullare l'iscrizione in caso di impossibilità a partecipare, grazie.
Prima di analizzare WinRT bisogna tornare indietro nel tempo e ripercorrere l'evoluzione dei linguaggi.
Il linguaggio C ha consolidato un modo standard per interoperare in due diversi modi:
- A livello sorgente grazie alla standardizzazione ANSI del 1989 (e successive)
- A livello binario, grazie alle calling convention dell'architettura x86 (stdcall, fastcall, cdecl) che stabilisce il modo in cui sono passati i parametri (ed altro).
Ad oggi questo rimane il modo più diffuso di fare interoperabilità tra linguaggi e, anche eseguiamo chiamate PInvoke con il Framework.NET stiamo di fatto utilizzando queste calling convention.
Quando utilizziamo le Win32, stiamo chiamando le API con la calling convention "stdcall".
Come nota di colore, il mio primo beta testing fu del compilatore MASM (Macro Assembler) di Microsoft come conseguenza di un bug che trovai nella versione 5.1 proprio nelle calling convention del compilatore interoperando con il compilatore C dell'epoca (parliamo degli anni 80).
Con l'affermazione di C++ l'interoperabilità è sempre stata solo a livello sorgente. La commissione ISO (oggi presieduta da Herb Sutter) ha stabilito il primo standard nel 1998 (posteriore all'uscita di Visual C++ 6.0 che perciò è fuori standard) e successivi, fino ad arrivare all'attuale C++11 di questo Agosto 2011.
La commissione non ha mai stabilito alcuno standard a livello binario tanto che non è neppure possibile utilizzare librerie che provengono da due versioni differenti della stessa marca di compilatore. È sempre necessario ricompilare tutto con la stessa versione del compilatore C++.
Ecco alcuni dei problemi di uno standard binario per un linguaggio object oriented:
- definizione di un type system (pensiamo a quanti tipi 'string' sono stati creati in C e C++)
- gestione del ciclo di vita degli oggetti (costruzione e distruzione)
- definizione di uno standard per la "decorazione" applicata dal compilatore per differenziare le funzioni in overload
- definizione di incapsulamento a livello binario (C++ supporta l'ereditarietà private o protected, per cui solo il compilatore conosce l'esatto layout della classe. Da qui la necessità di separare i concetti di interfaccia binaria (virtual table) dalle sue possibili implementazioni in oggetti binari differenti
Parlando di sistemi distribuiti, il problema è ancora più complesso. Pensiamo ad esempio di dover invocare una funzione remota che ha per parametro un blob (Binary Large OBject). In linguaggio C questo buffer è definito da un puntatore che però non ha l'informazione della lunghezza del blob. In C++ il blob può essere incapsulato in una classe ma C++ non fornisce la semantica necessaria per dichiarare, durante l'invocazione della chiamata remota, il blob sia in ingresso, uscita o entrambe le direzioni.
In un sistema distribuito attraversare un "boundary" (confine) ha un costo. Se il blob fosse un parametro di un web service, il costo in termini di banda per spostarlo in una o l'altra direzione non potrebbe essere ignorato.
Per colmare queste lacune nasce IDL (Interface Definition Language a cura dell'Open Software Foundation Distributed Computing Environment Remote Procedure Call) che viene adottato da Microsoft per realizzare COM e dal mondo Unix per realizzare CORBA. La versione binaria dei metadati generata grazie a IDL, le type library, sono le moderne librerie binarie che permettono anche l'interoperabilità binaria tra linguaggi differenti.
Non posso biasimare Don Box quando affermava "COM is Love" indicando (mia interpretazione) finalmente COM come una reale soluzione pratica, vincente e performante per i problemi di compatiblità binaria, interoperabilità e comunicazione distribuita. Tutt'ora è una soluzione che funziona egregiamente in Windows e la più performante (escludendo ovviamente le API "C" in quanto non forniscono una soluzione ai problemi risolti da COM). Nota di colore: Nei corridoi di //build/, al termine della sessione di Herb Sutter ho visto passare Don Box e gli ho detto "So COM is still love" ed è stato un piacere vederlo sorridere.
Fino a qui siamo agli anni 90 al termine dei quali emergono diversi problemi:
- Il type system è inadeguato e troppo complesso (BSTR, VARIANT, SAFEARRAY, …) e spesso richiede un custom marshaler (un oggetto che sia in grado di descrivere come copiare il layout di memoria di un tipo custom)
- Le collection non sono native
- Il sistema di eventi basato sui connection point è complesso
- Il ciclo di vita degli oggetti basato sul reference counting deve essere gestito manualmente ed è complesso
- La registrazione di interfacce e classi (registry)
In C++ alcuni di questi problemi vengono colmati dalle librerie ATL (Active Template Library) ma rimane pur sempre una libreria disponibile solo in C++ e complessa da utilizzare.
Potenza hardware
A partire dalla fine anni 90 la potenza dei PC superava abbondantemente i requisiti di una applicazione standard. Questo è stato il trigger che ha visto la nascita di Java e poi del Framework.NET. In quel periodo storico l'overhead dovuto ai runtime e alla garbage collection era minimo rispetto ai benefici di produttività e manutenibilità. Inoltre, in assenza di un moderno standard C++ che ha visto la luce solo questo Agosto 2011, linguaggi come C# hanno avuto giustamente una vasta diffusione.
Il Framework.NET, basato nella sua infrastruttura su COM, riafferma diversi concetti che abbiamo già analizzato:
- Definisce un type system moderno
- Provvede alle specifiche CLI che permettono di utilizzare più linguaggi
- Definisce la compatibilità a livello binario
- Aumenta la ricchezza dei metadati rispetto a quelli forniti da IDL in COM (pensiamo a reflection)
- Definisce un Intermediate Language (IL) che permette il disaccoppiamento rispetto all'architettura di sistema (x86 / x64 / …)
In fondo il vero plus del Framework.NET è quello del runtime, da tanti vituperata, che ha comunque diminuito drasticamente il numero di bug nelle applicazioni moderne e un aumento incredibile della produttività che si traduce direttamente nella possibilità di creare applicazioni più sofisticate. Il resto erano già concetti presenti in COM anche se espressi in modo più complesso.
Non più solo PC
Siamo quindi ai giorni nostri e i requisiti sono nuovamente cambiati. Gli utenti infatti chiedono dispositivi sempre più piccoli e potenti (ma che per ovvi motivi non possono essere tanto potenti quanto lo è un PC). Questo requisito si soddisfa principalmente con due fattori: minore consumo di CPU e (come conseguenza) di batteria.
Se prima avevamo cicli da buttare, oggi il discorso è cambiato quel tanto da non poterlo più ignorare.
Un altro fattore non indifferente è che l'introduzione del runtime implica la gestione della sua versione. Garantire che una applicazione che gira su una versione di runtime possa girare anche su una diversa versione di runtime è molto complesso, forse una chimera.
I requisiti cambiano ancora:
- uso di codice nativo
- conservare la produttività della programmazione con .NET
- type system moderno
- performance
- eterogenità di linguaggi
- flessibilità nella gestione della versione
Il Windows RunTime (WinRT) getta le basi su questi concetti e ne aggiunge di nuovi che vedremo in prossimi post quali per esempio il meccanismo di attivazione e le chiamate asincrone.
WinRT non poteva che ripartire da un'infrastruttura ben consolidata nel sistema operativo quale COM, ma apportando una serie di modifiche utili a superare i problemi che abbiamo analizzato in precedenza.
WinRT conserva i meccanismi di layout degli oggetti, IUnknown con le sue AddRef, Release e QueryInterface. Niente più IDispatch che ha dato tanti grattacapi agli sviluppatori per fornire invece la IInspectable. Può sembrare paradossale come queste due interfacce, tra le altre cose, svolgano ruoli simili e cioè la scoperta dei metdati.
Non so se esistano altri precedenti nel mondo dei sistemi operativi, ma l'esposizione dei servizi del sistema operativo in modo object oriented è certamente un grosso salto in avanti. A partire dal prossimo post comincerò ad analizzare le varie parti di WinRT.
lunedì 19 settembre 2011
Per dirlo in due parole il responso è … troppo presto perché un utente possa giudicare Windows 8.
La //build/ conference da cui sono appena tornato è una developer conference che ha assorbito PDC (Professional Developer Conference) e WinHEC (Windows Hardware Engineering Conference). Le sessioni in agenda vanno infatti dai temi riguardanti il Framework.NET e il nuovo WinRT a quelli inerenti lo sviluppo di driver in user e kernel mode.
La user experience di Windows 8 doveva essere mostrata insieme a tutte le principali novità e infatti abbiamo visto la nuova shell basata sullo stile Metro ma questa è pur sempre una developer preview e quindi è ancora troppo presto per tirare le somme sull'experience degli utenti finali.
Le novità per gli utilizzatori di Windows erano in parte già state annunciate sul blog da Sinofsky dall'annuncio della doppia shell a tutti gli altri dettagli sull'aumentata usabilità della shell.
Come è stato annunciato nella prima keynote il Marketplace è ancora in costruzione e questo significa che un utente, in questo momento, dello stile Metro non se ne fa nulla. Le applicazioni in stile Metro sono solo quelle preinstallate, alcune delle quali (vedi twitorama) ancora incomplete anche se molto attrattive.
La scelta di avere la doppia shell è più che apprezzabile e va nella direzione di offrire agli utenti una nuova generazione di applicazioni senza per questo dover rinunciare ad una collaudata e funzionale operatività con Windows.
Il vecchio desktop rimane per ovvi e ottimi motivi e in più aggiunge nuove funzionalità in modo da migliorare la sua usabilità. La nuova shell Metro ha una serie di indubbi vantaggi per gli utenti:
- Le applicazioni sono reperibili sul marketplace. L'idea nata in casa Apple è indubbiamente un modo semplice e conveniente per reperire nuove applicazioni. Il markeplace provvede a sistemi di controllo che limitano al minimo i potenziali danni che un'applicazione può arrecare.
- Le applicazioni sono contenute in un singolo package (apex) che contiene tutto ciò che l'applicazione necessita. Sono autoconsistenti e la loro installazione/disinstallazione è solo una questione di aggiungere/rimuovere il package e nulla di più.
- Il package contiene, tra le altre cose, il manifest che informa Windows sulla categoria di API che l'applicazione intende utilizzare (accesso alla rete, webcam, storage locale, etc.)
- Le applicazioni hanno la possibilità di utilizzare le API di base (le nuove WinRT) oppure dei servizi locali che vengono visti sotto forma di "Contracts". In questo modo ogni applicazione ha la possibilità di utilizzare le funzionalità di Search di sistema, condividere una risorsa su un social network etc. etc. Il tutto è naturalmente vincolato dalle permission che l'applicazione richiede e che l'utente è disposto a concedere.
- La vita delle applicazioni è più simile ad un device come cellulare o tablet. Il sistema operativo ora può ridurre a "sospeso" un processo in modo che non consumi risorse.
- Le applicazioni possono solo utilizzare funzionalità compatibili con la modalità Metro.
- Le applicazioni Metro devono essere fluide. Per questo motivo Microsoft ha deciso che le applicazioni Metro non avrebbero mai dovuto poter chiamare funzioni di libreria che blocchino il thread corrente per più di 50ms.
Questo sembra un punto poco rilevante invece è gigantesco, sia per l'impatto che ha sull'usabilità, sia per tutto quello che comporta a livello di librerie, linguaggi e tools che discuterò in altri post.
A mio avviso Microsoft ha fornito una risposta molto convincente dal punto di vista tecnologico, guidato dai due fattori più importanti: l'hardware disponibile sul mercato e le necessità degli utenti.
- L'hardware ha guidato verso la ricerca spinta di performance ed infatti WinRT, le novità del CLR 4.5 e l'uso di C++ sono in ottica performance.
- Gli utenti hanno chiesto usabilità, sicurezza e disponibilità di device e come conseguenza è nato il Metro-style, i packages, i Contracts, Windows per CPU ARM e la gestione asincrona.
Per concludere gli utenti hanno una piattaforma che potenzialmente è molto potente ma che in assenza del marketplace e di applicazioni non è giudicabile. Sarebbe totalmente errato giudicare Windows 8 utilizzando da un tablet che deve necessariamente utilizzare il vecchio desktop di Explorer. La piattaforma tecnologica verrà giudicata non solo dagli addetti ai lavori ma anche dalle applicazioni che saranno sul market. Se la grande maggioranza delle applicazioni dovessero offrire in futuro scarse funzionalità o problemi ricorrenti, significherebbe che Microsoft non ha fornito gli strumenti sufficienti a costruire buone applicazioni. Personalmente sono convinto del contrario perché tecnologicamente mi convince molto.
Nei prossimi post analizzerò nel dettaglio questi ed altri punti sotto il punto di vista dell'architettura del sistema operativo.
giovedì 15 settembre 2011
Tempo di recuperare le prime informazioni su WinRT, ecco quanto ho saputo parlando direttamente con diverse persone di diversi team.
Esistono due stack in Windows 8 per costruire applicazioni:
- Modalità classica (Win32 / .NET)
- Modalità Metro-Style
La modalità classica è quella che tutti conosciamo, non cambierà e sarà mantenuta per il futuro. Le applicazioni WPF, Winform e Html continueranno a funzionare. Queste applicazioni funzionano nell'ambiente del desktop classico e vengono aperte in Explorer come lo conosciamo adesso.
Le applicazioni NON possono usare entrambe le modalità. Se usano WinRT non possono usare Win32. Se usano Win32 non possono usare WinRT e perciò non sono Metro (e quindi girano nel vecchio desktop).
Nel contesto di applicazioni server tutto ciò che oggi abbiamo con il .NET Framework non ha senso che venga cambiato. Il Framework c'è e rimarrà con tutto ciò che già conosciamo.
Nel contesto di applicazioni client, può rimanere tutto come era prima (che verrà supportato) ma non potrà avere lo stile Metro.l Per essere "Metro" una applicazione deve seguire un nuovo corso e nuove modalità (vedi sotto).
…prendere un bel respiro…
La modalità Metro-Style è completamente nuova ed ha una serie di interessantissime caratteristiche:
- Metro non è solo uno stile grafico ma un insieme di specifiche per interagire con il sistema operativo. Il Metro di Windows 8 è radicalmente differente (come meccanismo) da quello di Windows Phone.
- Ogni applicazione è isolata, può utilizzare solo ciò che viene permesso dall'utente. Lo sviluppatore richiede i permessi tramite un manifest che viene controllato da WinRT tramite un broker che funziona da supervisore sulle attività dell'applicazione. L'ambiente in cui gira l'applicazione non è una virtual machine, non è il .net framework
- Il deploy delle applicazioni viene fatto tramite un package che contiene tutto ciò che serve allo Store per installare l'applicaizone sulla macchina. Le discussioni sullo Store privato (aziendale) sono tutt'ora sotto discussione.
- Tra i meccanismi più interessanti ci sono i Contracts che permettono all'applicazione di dichiarare come vuole interagire con le altre app e il sistema operativo (leggere un feed, una pagina facebook, cercare, etc.)
WinRT:
- È il Windows Runtime che espone le funzionalità del sistema operativo in modo Object Oriented.
- Non è codice managed e non necessita del .NET Framework
- Ha delle "Projection" che permettono ai vari linguaggi di interagire con il sistema operativo (C++, C#, VB.Net, Javascript)
- I linguaggi managed sopra WinRT hanno sempre bisogno del CLR e il Framework fornito con Win8 è la versione 4.5
- WinRT è costruito con tecnologia COM e conserva tutti i relativi meccanismi (IUnknown, AddRef/Release, Apartment per i modelli di threading, la message pump per gestire le STA).
- WinRT semplifica molti concetti COM. Per esempio elimina i Connection Points per gli eventi e la IDispatch per permettere ai linguaggi dinamici di interagire con esso.
- Il type system di WinRT è ristretto ma più ampio di quello COM. Per esempio non esiste più il BSTR ma la stringa ha un layout di memoria analogo a quella usata dal CLR. Questo permette di evitare le copie durante il marshalling e quindi di esporre la stessa zona di memoria sia al codice nativo che managed senza penalizzazioni di performance.
- Tra le novità nel type system ci sono le collection (anche di tipo observable) che sono costruite/mappate automaticamente dalle projection.
- Le projection di C++ mappano direttamente su strutture compatibili alle STL (Standard Template Library).
- Le projection di WinRT sono customizzate linguaggio per linguaggio e permettono di fornire la migliore resa in performance.
- È possibile scrivere estensioni di WinRT per esporre codice nativo custom alle applicazioni ma queste estensioni sono private di una applicazione e non possono essere condivise (niente regsvr32)
- I Contratti di Metro sono esposti come interfacce COM e la maggior parte di developer non avrà mai bisogno di scendere a livello di interfaccia COM per fruirne
- A livello più basso esiste WinRL, una libreria C++ usata dal team di Windows per costruire tutto ciò che WinRT espone. Si ritiene che nessuno ne abbia bisogno (tranne il sottoscritto ovviamente)
- Il versioning di WinRT è basato sui concetti COM e prevede le estensioni che verranno nelle future versioni del sistema operativo
Il Framework.NET:
- È utile a chi preferisce avere i servizi del CLR (Garbage Collection, etc.) e di conseguenza verrà usato C# e VB.NET
- Non è indispensabile e perciò Javascript e C++ non ne hanno bisogno.
- Molte librerie della BCL (Winform, e tutto ciò che fa I/O su video, disco e quant'altro) non sono utilizzabili dalle applicazioni Metro perché queste devono utilizzare solo WinRT. Tra questo tutto ciò che concerne XAML perché il suo engine (Metro-style) è stato riscritto in codice nativo.
- Esiste un nuovo interprete XAML scritto in codice totalmente nativo che mappa i controlli XAML su quelli nativi WinRT
- Allo stesso modo (stile phonegap per chi lo conosce) i tag html5 vengono mappati sui controlli nativi WinRT
- XAML e Html5 sono paritetici, interscambiabili e siedono sopra l'engine grafico (basato su DirectX) che renderizza le applicazioni Metro
I Tools. Oltre a quanto già visto e detto nelle keynote:
- Visual Studio 11 include tutto ciò che serve per creare il package e pubblicarlo sul Windows Store che non è ancora disponibile.
- Lo store privato è in fase di definizione.
- WinDBG rimane ma tutte le sue funzionalità sono state integrate dentro Visual Studio
- Visual Studio 11 include i wizard per creare driver in kernel mode, user mode, i test (static analisys) e il remote debugging (compresi i reboot e l'installazione dei certificati sulla macchina remota)
Stay tuned. Questo è solo l'inizio.
Il mio commento? WOW, è fantastico e finalmente c'è la vera platform che aspettavo da Microsoft.
So che probabilmente ci saranno tante domande e commenti ma please abbiate pazienza perché qui a build il ritmo è frenetico.
venerdì 2 settembre 2011
Il primo test che ho effettuato è già concluso miseramente.
Il modello di prova ha una serie di entities e ciascuna di queste ha i corrispettivi 'details' (Contact => ContactDetails, Document => DocumentDetails, etc.).
Ho scelto di avere una sola tabella Details per cui non posso avere la FK in Details che punta alla Contact e alla Document.
Creo quindi il DomainService in un progetto RIA, dopo aver cancellato il progetto Silverlight che è inutile per questo esempio:
[EnableClientAccess]
public class TestService : DbDomainService<BizContext>
{
[System.ServiceModel.DomainServices.Server.Query(IsDefault = true)]
public IQueryable<Contact> GetProducts()
{
return this.DbContext.Contacts;
}
...
Configuro l'endpoint (nel mio caso oData ma potrebbe essere anche SOAP o Json):
<system.serviceModel>
<domainServices>
<endpoints>
<add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</endpoints>
</domainServices>
E purtroppo ottengo una YSOD con questo errore:
Unable to retrieve association information for association '….DataLayer.Contact_Details'. Only models that include foreign key information are supported
Un vecchio post conferma i sospetti, la FK è indispensabile.
A questo va aggiunto il noto problema delle relazioni molti a molti (http://forums.silverlight.net/p/90385/346173.aspx) (http://social.msdn.microsoft.com/Forums/is/adodotnetentityframework/thread/cc48da63-502d-4429-b90a-0c558b1b9c94) che addirittura è sfociato in un progetto di workaround su codeplex (http://m2m4ria.codeplex.com/).
I RIA services sono indubbiamente una manna per chi fa RAD e le più recenti aggiunte dell'endpoint JSon per supportare i client jQuery sono vere killer features.
Ma qui stiamo partendo dal presupposto che il Modello venga prima di tutto. Quindi:
- per i più svariati motivi viene prima fatto il design delle entity
- poi mappo le entity al database con la fluent-API della Code-first, e genero il DB di conseguenza
- quindi voglio 'nascondere' tutto dietro un servizio in modo da poter presentare i dati con la fondamentale IQueryable e per client di tipo differente:
- Silverlight via soap
- jQuery via json
- altri client via oData
In quest'ottica non posso stravolgere il modello solo perché RIA non capisce bene il mapping di EF 4.1 e quindi per certi scopi non sono la soluzione. Un vero peccato perché si perdono un certo numero di facilities che sarebbero realmente molto comode.
Altri esperimenti in vista …
giovedì 1 settembre 2011
In uno scenario POCO che utilizza Entity Framework 4.1 (code-first) di default abbiamo in regalo il tracking dei cambiamenti apportati alle entities.
Caso 1.
Category cat;
System.Data.EntityState state;
using (BizContext ctx = new BizContext())
{
cat = ctx.Categories.First();
cat.Name += "X";
state = ctx.Entry(cat).State;
Console.WriteLine(state);
}
Il risultato di questo codice è "Modified". Dietro le quinte infatti EF chiama ctx.ChangeTracker.DetectChanges(); che esegue il confronto delle proprietà delle entity dichiarate nel context BizContext che deriva da DbContext.
Nessun timore per le performance, l'automatismo si può disabilitare ed eseguire il controllo, se richiesto, on-demand:
using (BizContext ctx = new BizContext())
{
ctx.Configuration.AutoDetectChangesEnabled = false;
cat = ctx.Categories.First();
cat.Name += "X";
ctx.ChangeTracker.DetectChanges();
state = ctx.Entry(cat).State;
Console.WriteLine(state);
}
Naturalmente il controllo verifica che i valori siano effettivamente differenti, per cui se si scrive una cosa di questo tipo:
cat.Name = string.Copy(cat.Name);
l'entity non verrà rilevata come modificata.
CASO 2.
Fin qui tutto ok. Lo scenario però è troppo semplice perché abbiamo imparato che gli scenari reali sono n-tier o comunque disconnessi (come nel caso delle web application) di conseguenza serve fare qualcosa di più.
using (BizContext ctx = new BizContext())
{
cat = ctx.Categories.First();
}
cat.Name += "X";
using (BizContext ctx = new BizContext())
{
ctx.Categories.Attach(cat);
state = ctx.Entry(cat).State;
Console.WriteLine(state);
ctx.MarkAsModified(cat); // manuale!
state = ctx.Entry(cat).State;
Console.WriteLine(state);
}
Il metodo MarkAsModified l'ho aggiunto alla mia classe BizContext ed è definito in questo modo:
public void MarkAsModified(object entity)
{
var ctx = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)this).ObjectContext;
ctx.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Modified);
}
In questa seconda casistica:
- dopo aver chiuso il context, modifichiamo l'entity che perciò è disconnessa
- riapriamo il context ed eseguiamo l'attach, dopo il quale sfortunatamente l'entity viene segnata come 'unchanged'
- dobbiamo quindi essere noi a marcarla come modificata (MarkAsModifid) e finalmente entity framework potrà lanciare le update sull'invocazione della SaveChanges (non presente nello snippet)
CASO 3.
Il problema di questa soluzione è che abbiamo perso del tutto il tracking che dovrà esser fatto perciò manualmente. Lo scenario è comunque valido per certe applicazioni e l'unica accortezza sarà quella di impostare AutoDetectChanges a false in modo da evitare inutili perdite di tempo da parte di EF.
Volendo recuperare il meccanismo di tracking, ecco il terzo caso:
using (BizContext ctx = new BizContext())
{
cat = ctx.Categories.First();
}
cat.Name += "X";
using (BizContext ctx = new BizContext())
{
IObjectContextAdapter adapter = ctx as IObjectContextAdapter;
var objctx = adapter.ObjectContext;
var current = ctx.Categories.Where(c => c.Id == cat.Id).FirstOrDefault();
if (current == null)
{
ctx.Categories.Add(cat); // era stato cancellato da un altro utente
}
else
{
// ObjectStateEntry entry = objctx.ObjectStateManager.GetObjectStateEntry(current);
// var s1 = entry.State;
// entry.ApplyCurrentValues(cat);
// var s2 = entry.State;
objctx.ApplyCurrentValues<Category>("Categories", cat);
state = ctx.Entry(current).State;
Console.WriteLine(state);
}
}
Il nuovo flusso dopo la solita modifica è il seguente:
- recupero l'ObjectContext a partire dal DbContext
- carico in memoria la versione attualmente su DB (current)
- se non la trovo significa che un altro utente l'ha cancellata. Nell'esempio la re-inserisco ma potrei ovviamente decidere di lanciare un'eccezione
- se la trovo chiedo a EF di impostare i valori 'attuali' con quelli che ho modificato (cat) quando ero disconnesso
- leggo lo stato della Entity e ottengo finalmente 'Modified'.
Le righe commentate sono un modo alternativo di eseguire la ApplyCurrentValues. Entrambe arrivano allo stesso risultato.
Tutto questo prescinde dall'uso di WCF Data Services (ancora in CTP) o di RIA che sono stati aggiornati per lavorare in tandem con EF 4.1 ed il tracking.
Una precisazione: perché uno scenario POCO? Perché sempre di più sarà utile lavorare serializzando in json e reidratare le entity sul lato server. Perciò POCO e disconnesso diventeranno sempre più strumenti ordinari. Se poi abbiamo i nuovi RIA con il supporto a json tanto meglio ma ovviamente dipende dal contesto lato server.
martedì 30 agosto 2011
Da quando Steven Sinofski sta bloggando (http://blogs.msdn.com/b/b8/) supportato dal suo team, sulla nascita di Windows 8, stanno emergendo diverse chicche molto interessanti.
Immagino che Utenti e IT-Pro siano elettrizzati (positivamente o negativamente a seconda del gusto personale) su queste novità. Personalmente sto ancora aspettando che su una gerarchia MSDN venga postato qualcosa che riguardi lo sviluppo sotto Windows 8.
Dopo la fanfara che ha preannunciato Html5 di diverse settimane fa, l'ultimo blog post ha mostrato che nella shell avremo il ribbon. Personalmente sono un entusiasta del ribbon ma sinceramente non è il livello di novità che può stuzzicarmi, tantomeno su un blog marcato MSDN. Intendiamoci USB3, supporto a ISO/VHD nella shell, e la gesione delle name collision sono features che apprezzo molto ma non è quello che mi aspettavo.
Come ho postato nei commenti dal punto di vista utente ci sono cose in sospeso fin da Vista come:
- la rotazione delle immagini sarà lossless? Oggi ancora non lo è e infatti io uso l'utility Jpeg Lossless Rotator
- la visualizzazione dei tiff multipagina che funzionava in XP (e non più a partire da Vista) è stata ripristinata?
- durante un copy, perché non posso fare una comparazione binaria del file (o di un suo hash) invece di dover lanciare "fc" da command prompt?
- …
Dal punto di vista developer sono terrorizzato al pensiero che l'unico libro che ti permetta di creare una shell extension sia ancora "Visual C++ Windows Shell Programming" di Dino. Ho sviluppato molte estensioni per la shell e per internet explorer (alcune attività sono simili) e ci sono un'enormità di hack da conoscere per sperare che siano sufficientemente stabili. Insomma tra modello di programmazione e sdk è una mezza tragedia.
Ho sempre giustificato questa lacuna sullo sviluppo per la shell, considerando la sua datazione preistorica, ma se viene annunciata una massiva ristrutturazione della shell mi aspetto che questi limiti e difficoltà siano superate.
Ormai manca poco e tra un paio di settimane vedrò con i miei occhi i risultati ad Anaheim. Il silenzio di questi mesi (ad oggi ancora nessuna agenda è stata pubblicata per la conference!) ha sollevato in me aspettative enormi e non posso credere che MS possa cercare di vincere la partita con Google ed Apple "solo" con una nuova "bella" versione di Windows … ci vuole molto ma molto, ma molto di più.
Le mie non sono critiche, nessuno è più ottimista di chi decide di andare ad Anaheim per vedere il lancio.
lunedì 22 agosto 2011
La prima premessa scontata di questo post è che sono un grandissimo fan di tutto lo sviluppo marcato Microsoft. Ho scatole storiche come il compilatore C 5.1 per DOS, QuickC, VC++ 1.0, Developer Studio, la Visual C++ subscription che fu, di fatto, la vera prima versione dell'abbonamento MSDN.
Non c'è dubbio che se il vostro target è quello di sviluppare per l'ambiente Microsoft, disponete dei tool più "cool" e, oltre a lavorare, riuscirete anche a divertirvi, perlomeno è quello che io e i miei collaboratori facciamo quotidianamente su PC.
Fino a pochi anni fa MS non solo aveva il sistema operativo più diffuso, Windows, ma anche la fetta di mercato prevalente del mercato mobile. La situazione di oggi è chiara a tutti e WP7 sta piano piano tornando nel mercato.
Come sviluppatore guardo a cosa ci offrono i vari vendor Apple, Android, BlackBerry, Nokia e Microsoft e senza dubbio, ancora una volta (come peraltro ho sempre sostenuto) lo sviluppo per Windows Phone è senza dubbio quello più agevole e "comodo".
C'è però un problema, della nostra comodità non importa a nessuno. Io ho sempre sviluppato per Windows certamente non solo perché aveva degli strumenti di sviluppo belli e geek ma perché Windows è il sistema operativo leader e quindi le mie applicazioni sono più fruibili rispetto a quelle sviluppate per tutto il resto. A quanto leggo su internet WP7 ha una fetta di mercato del 5.6% e quindi se devo sviluppare per il mercato mobile devo prima considerare gli altri device.
Devo aprire una parentesi ri-spiegando perché non sono un fan sfegatato di WP7: 1. è un prodotto a se stante invece di essere parte della "platform" (che è da sempre la mossa vincente di Microsoft). 2. perché avrei voluto, sempre in chiave platform, vedere dentro WP7 il kernel di Windows full e non, ancora, un derivato di Windows CE, come già scrissi tempo fa. Il secondo punto, a quanto si mormora, sembra diventerà finalmente realtà. Ancora una volta tutto questo, per noi sviluppatori, importa poco o niente. Non siamo noi a decidere dove sviluppare ma è il mercato a chiederti applicazioni per l'uno o l'altro device.
La seconda premessa (scontata anche questa) è che sono un super-tifoso dello sviluppo xaml-based. Da sempre attendo con ansia l'unione di WPF e Silverlight, ma, nel frattempo, ho realizzato tanti progetti WPF (alcuni dei quali sono un vero orgoglio per me) e altrettanti sono in corso di sviluppo. Dire che WPF mi piaccia è assolutamente riduttivo; Silverlight è decisamente una magnifica soluzione anche se lo vedo un po' spiazzato rispetto ai trend attuali, ma pur sempre un'adorabile tecnologia su cui ho sviluppato alcune piccole cosette che mi hanno dato molta soddisfazione.
Come sviluppatore devo osservare che i recenti propositi di Microsoft per Windows 8 e le recenti tecnologie annunciate in CTP da Microsoft mi impongono di prendere atto che conoscere lo sviluppo basato su Html5 e jQuery è un passo dovuto. Sempre per lo stesso teorema di cui sopra, cioè guardare cosa impone il mercato, non si può fare a meno di osservare che gli altri vendor puntano moltissimo su Html5 e jQuery. Browser e device (cellulari, slate e tablet) sono html5 ready (ok, con qualche colpo di tosse ma per lo più le cose funzionano benone). Dopo averci lavorato parecchio in questi ultimi mesi posso affermare che html5 e jQuery consentono di realizzare interfacce complesse e che coprono la maggior parte degli scenari più comuni.
Sempre sul lato device ho sempre riposto grande fiducia in "mono for Android" e "monotouch" (oggi di Xamarin) perché mi consentono di riutilizzare le mie conoscenze di C# e di Framework.net. Sembrava la soluzione più ovvia (arrivando dal Framework.NET) per sviluppare applicazioni basate su mono con C#. Il punto vincente delle librerie è di fornire un vasto wrapper su iPhone/Android per sfruttare a fondo le singole peculiarità. D'altro canto questo vantaggio significa anche di dover gestire due differenti applicazioni per iPhone/iPad e Android e questo implica un costo di ciclo di vita di cui bisogna tenere conto.
Aggiungi ancora che tutto il codice C# deve essere ampiamente elaborato per farlo girare su WP7 e sopratutto che l'interfaccia utente è un discorso ancora più complesso.
Perciò ho rivisto la mia posizione, ho fatto un passo indietro valutando altre soluzioni e mi accorgo che PhoneGap e Titanium sono l'uovo di colombo. Lungi da me confrontarli perché non ho ancora esperienza su questi due sdk, ma entrambi sono basati sul concetto di sviluppo della UI in Html5 e un layer di astrazione che permette di usare i device e la sensoristica in modo da eseguire il porting tra iPhone, Android ed altri device in modo molto semplice (leggo così da chi l'ha già fatto). Titanium permette di creare addirittura una applicazione "quasi-nativa" in modo da ottenere migliori performance. PhoneGap invece è più web-based e, grazie all'uso congiunto (opzionale) di jQuery-Mobile permette di riciclare l'applicazione come applicazione web classica.
Questi due ultimi toolkit (ce ne sono diversi altri) mi hanno favorevolmente impressionato perché:
- posso raggiungere più velocemente un target installato che supera abbondantemente il 60% del mercato (sono stato volutamente molto scarso)
- posso usare gli skill di html5 che saranno preziosi anche sotto Windows 8
- posso (almeno teoricamente) sviluppare anche per Windows Mobile 6 che nel mondo industriale c'è ancora anche se barcolla vistosamente (ma gli investimenti non si buttano velocemente)
Va da se che se ho i numeri (aka mercato) posso permettermi di realizzare tante applicazioni native quante sono le piattaforme di mercato. Costi alti ma giustificati se ho una applicazione come Angry Birds o anche un pochino meno di successo ;-)
A questo punto mi chiedo se l'SDK di Windows Phone 7 non abbia la necessità di essere riveduto e corretto. Se devo sviluppare mobile mi rivolgo prima a chi possiede lo share di mercato più alto e non credo proprio di dire nulla di folle. E se, fatto questo, voglio allargare a WP7 dovrei avere vita facile, e non cominciare un progetto da zero.
Proviamo ad applicare lo stesso ragionamento a chi ha lo share di mercato più alto nelle applicazioni PC, cioè Windows. Sullo sviluppo desktop non avrei dubbi a cominciare a sviluppare per Windows con Visual Studio una bella applicazione WPF o Silverlight, per poi cercare di salvare il salvabile utilizzando mono, moonlight o quant'altro vogliate. La prevalenza di Windows sul mercato è tale che per molte applicazioni posso anche permettermi di non fare alcun porting sugli altri OS. (Non me ne vogliano gli sviluppatori java, sul mio PC di sviluppo ho installato Eclipse, Aptana e Netbeans, ma se sviluppo per Windows e posso scegliere, la mia preferenza è per Visual Studio e il Framework.)
Per la Build Conference a cui parteciperò tra poche settimane non mi aspetto alcuna novità su questo specifico aspetto dello sviluppo ma ovviamente mi aspetto fuochi artificiali per tutto il resto.