Share via



2012

Volume 27

Windows Runtime - Reimagining App Development with the Windows Runtime

By Jason Olson | 2012

Developing Windows applications and using new Windows features from your programming language of choice has not always been simple and straightforward. For customers to have the best experience on Windows 8, and to empower developers to create the best apps on Windows, investments needed to be made to improve the end-to-end development experience on Windows. At the heart of these investments is the Windows Runtime (WinRT).

The Windows Runtime is part of a reimagining of the developer experience for Windows. It’s the modern Windows API surface used to create new Windows Store apps on Windows 8. The Windows Runtime is designed from the ground up to equally support several major programming languages (C#/Visual Basic, JavaScript and C++), to allow developers to leverage their existing skills and assets, to provide a thoughtful and consistently designed API surface, and to be deeply integrated into the developer tool chain.

The Windows Runtime Enables Language Choice

There are lots of app developers out there. They range from developers using JavaScript/HTML/CSS to create Web apps, to developers using C#/Visual Basic to create apps with the Microsoft .NET Framework, to native developers creating apps with C++. The Windows Runtime enables Windows Store apps to be written in any of these programming languages, empowering all of these developers to develop great Windows apps, as shown in Figure 1.

The Windows Runtime Enables New Windows Store Apps to Be Written in Many Languages
Figure 1 The Windows Runtime Enables New Windows Store Apps to Be Written in Many Languages

This is beneficial to both developers and consumers. There’s a huge market opportunity for developers to make money by developing Windows Store apps. And with the support for all major Microsoft languages, a huge number of developers are available to create the great Windows apps consumers want to buy and use.

As a developer, you have existing skills and experience in your particular programming language of choice. You also have a lot of existing assets you use when developing apps (such as existing code, build infrastructure and so on). You shouldn’t be required to learn an entirely new programming language and toolset simply to develop Windows Store apps on Windows 8 when there’s already a rich set of programming languages and development tools provided by Microsoft.

The Windows Runtime Is Natural and Familiar

The previous Windows development experience was designed when C was the dominant programming language, when exception-based code was uncommon and when being bound to a single language was acceptable for a Windows OS. Today’s modern developer world is quite different. Programming features such as namespaces, collections, events, asynchrony and so on aren’t just common today, they’re expected.

Let’s take a look at using one of the more common devices on Windows today: the webcam. This is how part of the webcam API was previously declared in Windows:

HWND VFWAPI capCreateCaptureWindow(
  LPCTSTR lpszWindowName,
  DWORD dwStyle,
  int x,
  int y,
  nit nWidth,
  int nHeight,
  HWND hWnd,
  int nID
);

Previous Windows APIs were primarily declared in a native header file (*.h) that shipped as part of the Windows SDK. The SDK also included a .lib file against which code using the API was linked. Windows APIs were implemented in C/C++ as native flat-C functions or as native COM components and packaged in a .dll file shipped as part of Windows. The programming model was designed natively with performance in mind.

There were no namespaces, modern collections or true exceptions. Even for classic native developers the development experience wasn’t ideal, as there were problems with IntelliSense, code browsing, lack of namespaces and more.

This purely native platform presented real usability problems as well for .NET developers trying to use Windows APIs, as shown in Figure 2.

Figure 2 The Previous Purely Native Platform Presented Real Usability Problems

[DllImport("avicap32.dll", EntryPoint = "capCreateCaptureWindow")]
static extern int capCreateCaptureWindow(
  string lpszWindowName, int dwStyle,
  int X, int Y, int nWidth, int nHeight,
  System.IntPtr hwndParent, int nID);
[DllImport("avicap32.dll")]
static extern bool capGetDriverDescription(
  int wDriverIndex,
  [MarshalAs(UnmanagedType.LPTStr)] ref string lpszName,
  int cbName,
  [MarshalAs(UnmanagedType.LPTStr)] ref string lpszVer,
  int cbVer);

Somebody needed to write a bunch of code to manually fill that gap between your code and traditional Windows APIs. If nobody had, you’d be left trying to write this complicated code yourself. Many resources for developers are aimed specifically at addressing this gap, including pinvoke.net, the Vista Bridge sample library (code.msdn.microsoft.com/VistaBridge) and the Windows API Code Pack for Microsoft .NET Framework (code.msdn.microsoft.com/WindowsAPICodePack).

Now, with Windows 8, you can use Windows APIs out of the box the day Windows ships, the exact same way you use other APIs in your apps today (such as in the .NET Framework for C#/Visual Basic developers). Code no longer needs to be written to fill the gap between your code and traditional Windows APIs. For example, using the webcam is much more straightforward today:

using Windows.Media.Capture;
MediaCapture captureMgr = new MediaCapture();
await captureMgr.InitializeAsync();
// Start capture preview; capturePreview
// is a CaptureElement defined in XAML
capturePreview.Source = captureMgr;
await captureMgr.StartPreviewAsync();

So how is using the Windows Runtime natural and familiar for developers? Because many apps retrieve data from the Internet, let’s examine this question in the context of a common networking scenario: retrieving an RSS feed. Here’s C# code to retrieve such a feed asynchronously:

var feedUri = 
  new Uri("https://www.devhawk.com/rss.xml");
var client = new Windows.Web.Syndication.SyndicationClient();
var feed = await client.RetrieveFeedAsync(feedUri);
var title = feed.Title.Text;

Here’s the equivalent Visual Basic code:

Dim feedUri = New Uri("https://www.devhawk.com/rss.xml");
Dim client = New Windows.Web.Syndication.SyndicationClient();
Dim feed = Await client.RetrieveFeedAsync(feedUri);
Dim title = feed.Title.Text;

Except for the root namespace (Windows), there’s not much different in this code from code you already write with the .NET Framework. There are namespaces. There are classes and constructors. There are methods and properties. Identifiers are Pascal case because they’re in the .NET Framework, and we also use the await keyword for asynchronous programming—everything a developer expects when writing code using C# and Visual Basic today.

Similar to the C#/Visual Basic development experience, C++ uses namespaces, classes, constructors, methods and properties. You can also use built-in C++ types such as strings (as opposed to previous Win32 data types). Standard operators such as “::” and “->” and others are also used as expected. And for asynchronous programming, we provide a Concurrency Runtime-like experience. Here’s C++ code to retrieve an RSS feed asynchronously:

auto feedUri = ref new 
  Windows::Foundation::Uri("https://www.devhawk.com/rss.xml");
auto client = ref new Windows::Web::Syndication::SyndicationClient();
task<SyndicationFeed^> 
  retrieveTask(client->RetrieveFeedAsync(feedUri));
retrieveTask.then([this] (SyndicationFeed^ feed) {
  this->title = feed->Title->Text;
});

Finally, there’s JavaScript, which shows some interesting differences in equivalent code:

var title;
var feedUri = 
  new Windows.Foundation.Uri("https://www.devhawk.com/rss.xml");
var client = new Windows.Web.Syndication.SyndicationClient();
client.retrieveFeedAsync(feedUri).done(function (feed) {
  title = feed.title.text;
});

You’ll notice in JavaScript that all methods and properties are camel case because it’s natural and familiar to JavaScript developers. We’re also using a promises framework with anonymous functions when writing asynchronous code. We continue to leverage the built-in types of the language here as well.

The developer experience is also familiar, with tooling features that developers expect, such as IntelliSense and functioning standard tools such as ILDASM and .NET Reflector (see Figure 3).

Visual Studio IntelliSense for WinRT APIs
Figure 3 Visual Studio IntelliSense for WinRT APIs

The Windows Runtime enables this natural and familiar experience by extending and combining foundational concepts from .NET and COM to add modern semantics to WinRT APIs, such as classes, constructors, statics and events. These semantics can be exposed in different ways from different languages, all depending on what’s natural and familiar to developers in that language.

This is possible because all WinRT APIs include metadata that programming languages use to know how that API is exposed via the Windows Runtime. WinRT metadata files use an updated version of the .NET metadata format. This metadata is available to every developer because it’s installed on every single Windows 8 machine.

By reimagining the Windows API development surface, it doesn’t feel like learning or using a new platform. It doesn’t feel “alien.” It looks and feels like code you’ve been writing. You’re leveraging the existing skills and assets you have when creating new Windows Store apps.

The Windows Runtime Is Rich in Functionality

The Windows Runtime has fewer APIs than Win32, so it’s easy to learn, yet it’s rich in functionality. The richness of the Windows Runtime is too much to cover fully in an article of this size, but both the standard Windows features and the new Windows 8 features you expect to be there are there, as shown in Figure 4.

The Windows Runtime Includes Standard Windows Features and New Windows 8 Features
Figure 4 The Windows Runtime Includes Standard Windows Features and New Windows 8 Features

And the Windows Runtime is consistently designed through the use of a single unified set of API design guidelines. You learn the concepts and design once with a single API, and then you can apply that knowledge when using different APIs across the entire Windows API surface. 

On the Windows Dev Center (dev.windows.com), you’ll find many samples that cover most of these areas. Following are some examples.

ContractsYou can let users search within your app when they select the Search charm and display suggestions in the Search pane. Your app can also share content with another app via the Share charm. Here are some examples:

SocialUsing classes from the Windows.ApplicationModel.Contacts namespace, you can launch the Contact Picker and acquire contacts. For apps that need to supply contacts to other apps, you can use the ContactPickerUI class to create a collection of contacts:

Media From simple media playback and media capture, to transcoding of media and playing media to external devices via the Play To contract, you’ll find Windows APIs in the Windows.Media namespace:

SecurityYou can retrieve credentials, which can then be passed to APIs that might require credentials (for example, to support single sign-on). You can also use password-based strong encryption to securely store private information on a local computer to protect credit-card accounts, bank accounts and software products. You can even perform many different forms of encryption using the Windows.Security.Cryptography namespace:

Networking/Web Whether you’re connecting to the network via TCP using the StreamSocket class, connecting via User Datagram Protocol (UDP) using the DatagramSocket, or simply querying for networking information status to figure out whether you can save some application data to a Web service or need to save it locally, you can find what you need in the Windows.Networking namespace:

This is not all the functionality in the Windows Runtime, of course. There’s much more functionality available to you as a Windows developer, and you can investigate further at the Windows Dev Center at bit.ly/yyJI2J.

The Windows Runtime Is Fast and Fluid (Native and Async)

The Windows Runtime is implemented at the lowest level as native objects with a binary contract, but it’s exposed to the world through metadata, a common type system and shared idioms. WinRT APIs continue to provide the fast performance capabilities of previous Windows APIs while also providing a modern development experience, as I demonstrated earlier.

For apps to remain fluid and responsive is a different challenge. We human beings instinctively multitask, which directly impacts how we expect apps to respond to us. We expect apps to be responsive to all interactions. When we use our favorite news-reading app, we want to add news feeds, read news articles, save news articles and so on. And we should be able to do all of these things even when the app is retrieving the latest articles from the Internet.

This becomes especially important when we’re interacting with apps using touch. We notice when the app doesn’t “stick” to our finger. Even minor performance problems can degrade our experience and break the fast and fluid feeling.

Many modern apps connect to social Web sites, store data in the cloud, work with files on the hard disk, communicate with other gadgets and devices, and so on. Some of these sources have unpredictable latencies, which makes creating fast and fluid apps challenging. Unless built correctly, apps spend more time waiting for the outside environment and less time responding to the user’s needs.

Addressing this connected world is a core principle of the Windows Runtime. You, the developer, should fall into “The Pit of Success” (see bit.ly/NjYMXM) when creating apps that are connected to the world. To achieve this, potentially I/O-bound or long-running APIs are asynchronous in the Windows Runtime. These are the most likely candidates to visibly degrade performance if written synchronously (for example, they likely could take longer than 50 ms to execute). This asynchronous approach to APIs sets you up to write code that’s fast and fluid by default and promotes the importance of app responsiveness when developing Windows Store apps.

To understand more about the asynchronous nature of the Windows Runtime, you can read the blog post, “Keeping apps fast and fluid with asynchrony in the Windows Runtime,” at bit.ly/GBLQLr.

The Windows Runtime Enables Hybrid Apps

A powerful feature of the Windows Runtime is that you aren’t restricted by the programming language with which you choose to create your app. You aren’t limited to just the libraries and code available to that programming language environment. You can use the language, library or component that’s best suited for the job. It might be an open source library.

What if you’re writing a game with JavaScript/HTML/CSS and you want a very fast physics library? You can use Box2D in C++. Writing a Windows Store app with JavaScript and want to work on some zipped files? You can use the zip functionality in the .NET Framework in a straightforward way. Creating a new Windows Store music app in C# and want to do some lower-level audio programming? No problem, just use Xaudio or WASAPI in C++. These capabilities are illustrated in Figure 5.

The Windows Runtime Enables Hybrid Apps
Figure 5 The Windows Runtime Enables Hybrid Apps

Let’s look at an example software synthesizer app using XAML written in C#. I want to add some cool filter support to it, so I’m going to leverage Xaudio to have direct control of audio buffers. I use C++/CX to build the APIs that will be exposed to the C# project.

First, I create a simple WinRT wrapper around the Xaudio functionality I want to expose (see Figure 6).

Figure 6 XAudioWrapper.h

#pragma once
#include "mmreg.h"
#include <vector>
#include <memory>
namespace XAudioWrapper
{
  public ref class XAudio2SoundPlayer sealed
  {
    public:
      XAudio2SoundPlayer(uint32 sampleRate);
      virtual ~XAudio2SoundPlayer();
      void Initialize();
      bool   PlaySound(size_t index);
      bool   StopSound(size_t index);
      bool   IsSoundPlaying(size_t index);
      size_t GetSoundCount();
      void Suspend();
      void Resume();
    private:
      interface IXAudio2*                m_audioEngine;
      interface IXAudio2MasteringVoice*  m_masteringVoice;
      std::vector<std::shared_ptr<ImplData>>  m_soundList;
    };
}

First, note the usage of the “public,” “ref” and “sealed” keywords in the class declaration. This is simply how you declare a public WinRT class in C++/CX. This will allow you to use this class from other languages such as JavaScript, C# or Visual Basic. It’s important to note that this is not managed C++ or C++/Common Language Infrastructure (CLI). This is not compiling down to Microsoft intermediate language; this is a native component through and through.

You’ll also notice that the public functionality (methods, properties and so on) of the class is limited to C++ built-in types or WinRT types. Those are the only types allowed for crossing the language boundary in WinRT components. However, you can use existing C++ libraries (for example, the Standard Template Library) as much as you wish in the implementation of your WinRT components.

For more details on creating WinRT components in C++, you can read the Windows Dev Center topic, “Creating Windows Runtime Components in C++,” at bit.ly/TbgWz7.

Now that I’ve defined the basic interface for my class, let’s take a quick look at some of the implemented methods (the details aren’t important) as shown in Figure 7.

Figure 7 XAudioWrapper.cpp

XAudio2SoundPlayer::XAudio2SoundPlayer(uint32 sampleRate) :
  m_soundList()
{
  ...
  XAudio2Create(&m_audioEngine, flags);
  // Create the mastering voice
  m_audioEngine->CreateMasteringVoice(
    &m_masteringVoice,
    XAUDIO2_DEFAULT_CHANNELS,
    sampleRate
  );
}
bool XAudio2SoundPlayer::PlaySound(size_t index)
{
  //
  // Setup buffer
  //
  XAUDIO2_BUFFER playBuffer = { 0 };
  std::shared_ptr<ImplData> soundData = m_soundList[index];
  playBuffer.AudioBytes = soundData->playData->Length;
  playBuffer.pAudioData = soundData->playData->Data;
  playBuffer.Flags = XAUDIO2_END_OF_STREAM;
  HRESULT hr = soundData->sourceVoice->Stop();
  if (SUCCEEDED(hr))
  {
    ...
  }
  ...
}

As you’ll notice from the code snippet in Figure 7, I’m using the Xaudio2 COM APIs available in the Windows SDK for Windows Store apps to wire up the audio engine. Additionally, I’m using C++ constructs and types beyond just the WinRT types to implement the necessary functionality.

Once I’ve defined and implemented my basic class, I can simply add a reference to my C++ project from my C# project. As a result, the class that’s exposed from my C++ project becomes available to my C# project (see Figure 8).

Figure 8 MainPage.cs

using XAudioWrapper;
namespace BasicSoundApp
{   
  public sealed partial class MainPage : Page
  {
    XAudio2SoundPlayer _audioPlayer = new XAudio2SoundPlayer(48000);
    public MainPage()
    {
      this.InitializeComponent();
    }
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
      _audioPlayer.Initialize();
    }
    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
      _audioPlayer.PlaySound(0);
    }
  }}

You can see that, though the XAudioWrapper was written in native C++, it can be used as if it were a regular .NET class. I reference its namespace, instantiate the component and start invoking the various methods it exposes—all without requiring any DllImports to call into the native code!

There are no boundaries. As a JavaScript developer, you aren’t limited to JavaScript libraries. As a C#/Visual Basic developer, you aren’t limited to .NET libraries. And as a C++ developer, you aren’t limited to C/C++ libraries. Will you need to create your own components often? Perhaps not. But the option is available to you.

To sum up, the Windows Runtime is at the heart of creating Windows Store apps on Windows 8. It provides a powerful platform on which to create Windows Store apps. The Windows Runtime provides a development surface that has a consistent and thoughtful design and is rich in functionality. And whether you’re a JavaScript developer, C#/Visual Basic developer or a C++ developer, you can now be a Windows developer creating new Windows Store apps for Windows 8.

Frequently Asked Questions

Q. Is the Windows Runtime a replacement for the CLR or the Microsoft .NET Framework?

A. No. The Windows Runtime does not replace the .NET Framework or any other frameworks. When you build a Windows Store app in C#, your code is still executing using the CLR. Not only that, but a subset of the .NET Framework (as well as Win32 and COM) is available for you to use when building your Windows Store apps.

Q. So when writing Windows Store apps in C++, I’m using C++/CLI?

A. No. Code using the Windows Runtime for Windows Store apps is written using C++/CX. Though it may look like C++/CLI at first, it is truly native. You won’t introduce garbage collection or other C++/CLI features into your native app.

Resources

For more information, check out the following resources:


Jason Olson is a senior program manager working on the Windows Runtime at Microsoft. When he’s not working on Windows, he can be found playing piano around the Seattle area and spending time with his wife and two boys.

Thanks to the following technical experts for reviewing this article: Noel Cross, Anantha Kancherla, Ines Khelifi, John Lam, Martyn Lovell, Harry Pierson, Mahesh Prakriya and Steve Rowe