posts - 644, comments - 1986, 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

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!

Print | posted on Monday, October 24, 2011 2:50 PM |

Feedback

Gravatar

# re: Essential WinRT parte 3: i contratti e l'attivazione

interessante, non capisco se il meccanismo di attivazione è pensato solo per applicazioni con una GUI oppure è pensato, come per COM, anche per componenti ui-less in process oppure out-of-process (esempio: libreria che zippa file, piuttosto che compoenente "server" che viene chiamato in automazione tipo office etc)
11/26/2011 3:09 PM | Dario Cecere
Gravatar

# re: Essential WinRT parte 3: i contratti e l'attivazione

L'attivazione per contratto oggi è legata ad un'interfaccia grafica. Per esempio il search espone la UI per i risultati e lo share chiede conferma di ciò che si condivide.
Però le app metro hanno uno specifico punto di ingresso per ciascun contratto quindi potresti anche non emettere UI per una certa richiesta.
Credo di aver capito dove vuoi arrivare ma devi tenere conto che comunque sei in ambiente Metro quindi anche in assenza di UI, la tua deve essere una App che passa da Marketplace e vive nell'ambiente Metro e non ha relazione con il vecchio desktop o utilizza API che non siano compatibilit Metro.

Per l'attivazione di codice 'server' abbiamo già IIS, Windows Service, DCOM e quant'altro tu voglia usare che sicuramente resterà. Andare verso Metro non significa rinunciare a tutto ciò che abbiamo nel desktop oggi, perlomeno per i device per cui ha senso (non avrebbe senso il desktop classico su un cellulare :))
11/27/2011 11:52 AM | Raffaele Rialdi

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 2 and 3 and type the answer here:

Powered by:
Powered By Subtext Powered By ASP.NET