my notes on WinRT from great article by Peter Bright
“It took a long time for Microsoft to realize that effective touch applications had to be built with touch in mind from the outset, but realize it has, and Windows 8’s new Metro UI and Metro-style applications will give Windows the tablet interface it has always needed, but always lacked in the past.”
Just as WinRT takes the age old COM technology then updates and repurposes it for modern application development, it also does the same for C++/CLI (its .NET-oriented variation of C++). C++/CLI has been reborn as C++/CX. C++/CX makes use of the same extensions that C++/CLI adds—for example, using
^ instead of
ref class instead of
class—but changes their meaning. .NET is a garbage collected environment, so in C++/CLI,
^ is used to refer to garbage collected objects. COM, however, is reference counted, so in C++/CX,
^ is used to refer to reference counted objects.
Win32 and WinRT
First, the WinRT library is a layer on top of Win32. It uses some new bits of Win32, such as Direct2D and DirectWrite. It uses some much older bits of Win32, such as the shell library (a disparate set of utility functions for, among other things, manipulating files and paths) and Winsock (the network API). But either way, it uses Win32. It is not a sibling of Win32, it is not an alternative of Win32; it is a client of Win32, a consumer of Win32, just like every other application.
Second, Metro-style applications do not use WinRT exclusively. WinRT is very important, and I think that any reasonable Metro-style application will end up using WinRT, at least a little bit, but not exclusively. But there are also some important APIs that Metro-style applications can use, but which don’t form a part of the WinRT COM world at all. Probably the most important of these is Direct3D 11. Games in the Metro world can use Direct3D 11, but they’ll have to be written in C++ to do so, and they’ll have to use Direct3D’s traditional COM-like design without projections or metadata or any of the other pieces of WinRT infrastructure.
There are also lots of portions of Win32 available to Metro apps that have partial WinRT alternatives, but which are also exposed directly for when the WinRT alternatives aren’t flexible enough. For example, WinRT has APIs for opening, reading, and writing files, but also provides access to low-level Win32 functions (some new, some old) that perform the same functions.
This is true even of the ARM-based Windows RT. Though third-party desktop applications are banned on Windows RT, this hasn’t allowed Microsoft to strip out unnecessary Win32 cruft. It’s all still there, powering WinRT.
WinRT borrows heavily from WPF and Silverlight. It uses a new dialect of XAML, the same XML-based markup language for GUI design, and uses essentially the same techniques for plumbing application data into the GUI, and responding to user input. There is an arguably important difference, however: WinRT’s XAML toolkit is written in native code, whereas all the XAML toolkits that went before it (WPF, Silverlight, and Windows Phone—the three are, regrettably, similar, but not entirely compatible) were predominantly written in .NET code
WinRT addresses the “don’t block the input thread” issue by making its I/O APIs asynchronous. Dogmatically so. They’re all asynchronous, all the time, for both disk and network I/O (though some of the Win32 APIs that Metro applications are permitted to use remain synchronous). Each asynchronous operation can have a callback specified, and the callback will be run whenever the operation is complete. WinRT has a set of four standard interfaces that are used by all asynchronous operations, and another set of interfaces for the callbacks themselves.
For non-I/O tasks, WinRT eschews the traditional Windows solution of threads. In fact, WinRT offers no API for creating a thread at all. WinRT programs are still multithreaded, but the operating system, rather than the application, has responsibility for managing those threads. What it does offer instead are thread pools. Thread pools are groups of system-managed threads that sit around waiting to be given some work. When an application wants to do some processing in the background, it assigns the piece of work to the thread pool. The pool picks one of its threads at random, uses it to perform the work. When it’s finished, the thread goes back to sleep, waiting for the next item.
This design decision is a little strange. It makes porting any existing applications more than a little awkward, as most existing applications expect to create their own threads on an as-needed basis (though Microsoft developers have produced a library that implements the old Windows threading API on top of the WinRT thread pool API to ease this migration), and it’s extremely poorly documented, giving no indication of what happens if, for example, more work is given to the thread pool than the pool has threads available (it probably adds more threads, but the policy it uses for doing so matters; if it doesn’t add enough threads, it can break applications).
The WinRT application model is far more constrained than the Win32 environment of old. WinRT applications will be constrained to sandboxes. They will be isolated both from each other and the operating system: WinRT applications won’t in general be allowed to communicate each other, whether for good reasons (such as plug-ins) or bad (such as spyware). They will have only limited access to the file system: by default, they will only be able to open or save files that the user has explicitly picked. Applications generally won’t be able to run persistently: the system reserves the right to suspend or kill any application in the background.
Chief among them is that WinRT has no mechanisms for interprocess communication (IPC). Normal Windows applications can communicate between one another in all sorts of ways; they can send messages between one another to simulate mouse and keyboard input (and more), they can use the clipboard, they can create local network connections, they can share pieces of memory, they can use certain COM-related technologies; there are lots of options. The problem with all of these systems is that they tend to be quite susceptible to various kinds of attack, and as such, all of them are off-limits to WinRT applications, except for the clipboard, for which there’s some support.
For these kind of communication tasks WinRT has a number of related, structured communication channels that Microsoft has called contracts and extensions. Contracts are for things like sharing data; they’re channels for applications to communicate with each other. Extensions are for applications to communicate with the operating system itself, and are used for things like handling specific file types and protocols, or providing camera effects.
Even with contracts, there’s no direct communication between applications. It’s all orchestrated by system components that pass the necessary data between applications, either directly or via files on disk. Applications have to declare which contracts they support, if any, and the operating system performs the necessary filtering required. For example, if the current app is offering up a piece of text to share, only those apps that declare that they are able to receive shared text will be made available.
In this way, the contracts retain the strict isolation between applications and protect them from the free-for-all that traditional Windows IPC implies.
WinRT is a curious beast. It brings together some of Microsoft’s oldest ideas—including COM and asynchronous I/O everywhere—and combines them with some of Microsoft’s newest ideas, such as XAML and Direct2D. Microsoft positions it as being a kind of new Windows subsystem, disconnected from the Win32 legacy, but it turns out to be just a nicer way of using the same old Win32 APIs that have been evolving for two decades now. It could be the future of Windows application development, but it doesn’t have to be. If it fails to attract developer and user interest, it could be sidelined or repositioned, perhaps by breaking down the wall between desktop apps and Metro apps and offering the same set of APIs to each.
In a sense, WinRT is much closer to something like MFC and .NET than Microsoft’s diagram and promotion lets on. MFC (“Microsoft Foundation Classes”) is a library that the company has offered C++ developers since the early 1990s that provides a set of classes built on top of Win32 that makes Win32 somewhat less painful to use and more “object oriented.” Fundamentally, WinRT, MFC, and .NET are all layers on top of Win32 (rather than replacements for Win32) that provide a “modern” development environment. The exact meaning of “modern” has changed over the years to accommodate different coding styles and practices, and .NET and MFC have some advantages that WinRT doesn’t (for example, much of their source code is published, making it much easier to figure out what’s going on behind the scenes and why things aren’t working), but the goal of all three has been the same: to make it easier to write software for Windows.