posts - 644, comments - 2003, trackbacks - 137

My Links

News

Raffaele Rialdi website

Su questo sito si trovano i miei articoli, esempi, snippet, tools, etc.

Archives

Post Categories

Image Galleries

Blogs

Links

lunedì 24 ottobre 2011

Essential WinRT parte 3: i contratti e l'attivazione

La nuova schermata di start di Windows 8 mostra una serie di "tile" che potrebbero sembrare una versione rinnovata dei vecchi shortcut:

SNAGHTML24b09627

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).

image

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.

image

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!

posted @ lunedì 1 gennaio 0001 00:00 | Feedback (2) |

Powered by:
Powered By Subtext Powered By ASP.NET