Using Windows 8* WinRT API from desktop applications

The Windows* Runtime API, also called WinRT, is the new core API for Windows 8* Store apps. It exposes all the full new Windows 8* features to developers, in an object-oriented and efficient way.

This API is written in C++ on top of Win32 and the COM interface. It is exposed out to other languages (in particular C++/CX, C#, Visual Basic* and Javascript*) via API meta-data files (.winmd files).

While you might think that WinRT is restricted to Windows 8* Store apps, Desktop applications have access to it as well. Some parts of the API are even restricted to desktop applications because they need to run outside of the Windows 8* Store apps sandbox, like PackageManager.

You can get information on which parts of the API are available directly from the MSDN library. There is a mention about compatibility at the top of most of classes.

What remains inaccessible from desktop applications is mostly what is specific to Windows 8* Store apps: design elements and contracts.

WinRT exposes its content to other languages via two major .winmd files :

  • Windows.winmd: C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral
  • Platform.winmd: C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\Microsoft.VCLibs\11.0\References\CommonConfiguration\neutral

They correspond respectively to the Windows namespace and the Platform namespace. The Windows namespace gives access to most of the Windows Runtime, and Platform contains important types like String.

Here are some interesting parts of Windows Runtime you can use from desktop applications:

  • Windows.Sensors (Accelerometer, Gyrometer, Ambient Light Sensor, Orientation Sensor, etc.)
  • Windows.Networking.Proximity.ProximityDevice (NFC)
  • Windows.Device.Geolocation (GPS)
  • Windows.UI.Notifications.ToastNotification
  • Windows.Globalization
  • Windows.Security.Authentication.OnlineId (including LiveID integration)
  • Windows.Security.CryptographicBuffer (usefull binary encoding/decoding functions)
  • Windows.ApplicationModel.DataTransfer.Clipboard (access and monitor Windows 8* Clipboard)

In this article, you can discover how to use WinRT from a desktop C# project as well as from a C++/CX or standard C++ project.

Using the Windows Runtime from a C#/.NET Project

By default, Visual Studio* 2012 doesn't give you access to the Windows Runtime from a regular desktop C# project.

You first need to declare that your project is targeting Windows 8.

Unfortunately VS2012 doesn't provide any graphical interface to do that, so you have to start by unloading your C# Project:

Then you can manually edit the .csproj file to add

  <PropertyGroup>
    <TargetPlatformVersion>8.0</TargetPlatformVersion>
  </PropertyGroup>

Reload your project:

Now your project is set to target the Windows 8* platform, and you can reference .winmd files from your project:

A new tab "Windows" should have appeared in the reference manager:

Check Windows to add Windows.winmd as a reference to your project. If that item isn't there, you can reference it manually from its location (C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\Microsoft.VCLibs\11.0\References\CommonConfiguration\neutral) using "Browse".

Now you are able to use the Windows Runtime from your desktop application, with full support from Intellisense:

You might need to add a reference to System.Runtime.WindowsRuntime.dll as well if you are using mapped types like Windows Runtime event handlers: 

That assembly resides in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5 .

WinRT C#/.NET Accelerometer example

using System;
using Windows.Devices.Sensors;
namespace CSApp
{
    class Program
    {
        static void Main()
        {
            Accelerometer accelero = Accelerometer.GetDefault();
            accelero.ReadingChanged += (Accelerometer sender, AccelerometerReadingChangedEventArgs args) =>
                {
                    Console.WriteLine(args.Reading.AccelerationX);
                };
            Console.Read();
        }
    }
}

Using the Windows Runtime from a C++ Project

You can consume the WinRT API both from C++/CX or purely standard C++. If you want to stick to standard C++, you have to use WRL: the Windows Runtime C++ Template Library, and directly handle COM objects.

Both solutions produce native code, but WRL is a lot more tedious to use than C++/CX.

C++/CX Solution

C++/CX looks like C++/CLI. The main difference between C++/CX and C++/CLI is that C++/CX doesn’t produce managed code at all, it's purely native.

You can find general documentation on C++/CX at the MSDN library, starting by a quick reference.

To enable its use in your C++ project, start by opening its properties.

In the C/C++->General tab, set “Consume Windows Runtime Extension” to Yes (/ZW):

Then set /Gm-, as /Gm is not compatible with /ZW:

Your project is now a C++/CX project.

Add Windows.winmd and Platform.winmd paths to “Additional #using Directories”:

In your source code, add:

#using <Windows.winmd>
 #using <Platform.winmd>

Now you are able to use the Windows Runtime from your C++ project, with full Intellisense support:

In order to be able to initialize Windows Runtime objects, your program need to have the Windows Runtime initialized.

To do so, the simplest way is to add [Platform::MTAThread] (or [Platform::STAThread]) attribute to the entry point of your program. You can otherwise manually call RoInitialize() and RoUninitialize().

C++/CX Accelerometer example

#include <iostream>
#using <Windows.winmd>
using namespace Windows::Devices::Sensors;
#using <Platform.winmd>
using namespace Platform;

[MTAThread]
int main(void)
{
 Accelerometer^ accelero = Accelerometer::GetDefault();
 accelero->ReadingChanged += ref new Windows::Foundation::TypedEventHandler<Accelerometer^,AccelerometerReadingChangedEventArgs^>(
 [](Accelerometer^ sender, AccelerometerReadingChangedEventArgs^ args){
 std::cout << args->Reading->AccelerationX << std::endl;
 });
 std::cin.get();
 return 0;
}

C++ WRL solution

With WRL, you directly manipulate COM objects exposed by WinRT. 

More information on how to use it can be found on msdn library:

For more complete information about compiler optimizations, see our Optimization Notice.

10 comments

Top
Johannes H.'s picture

Hello
Does this example still work?
I created a c++ win32 console app in visual studio and followed the instructions under C++/CX Solution and pasted the example code. I did however keep the #include "stdafx.h" at the top, not sure if this matters but not sure how to safely remove it either....
I get errors like:
c:\program files (x86)\microsoft visual studio 14.0\vc\include\vccorlib.h(693): error C2245: non-existent member function 'Platform::Details::Heap::Allocate' specified as friend (member function signature does not match any overload)

If I change the additional using directives to 8.1 I can compile it but when running I get lots of nullptr.

Anyone knows what is wrong?

 

Also can I add a package.appxmanifest to the project by the way?
I don't see it mentioned here but in many tutorials for UWP you seem to need it?

 

josip n.'s picture

Really helpful. Thank you a lot!!

Great!! This had me stymied for a day. Now on to my other C# problems....

Chirag Chinmay's picture

Thank you. I am new and this article will definitely help me in using Windows* Runtime API.

Adrian Stevens's picture

A big thank you for this - it makes porting between Windows Store and WPF so much easier.

Mubbasher M.'s picture

Hi, Can you please post or send me the source code for the C++ project.
Thanks

Xavier H. (Intel)'s picture

Maybe you can take a look at app.js
It will allow you to create an html5 desktop app and also have a C++ binding you can use to access sensors.
Chrome packaged apps may also be an option but I'm not sure you can do native calls using it.

kushagra-gour's picture

Thanks for your reply. So is there any way I could wrap my HTML5 app into something which can make the sensor API available to me.

Basically my exact requirement is that I have my HTML5 app (.html,.css,js files only) ready and I need to package it into an windows installer for Intel AppUp and also have sensor access in my app.
How to go about it?

Xavier H. (Intel)'s picture

Thanks Kushagra.

Sorry but there is no way to directly use WInRT from a browser, you need some native extensions.
There is already some for accessing sensors :
IE10 : http://html5labs.interoperabilitybridges.com/prototypes/device-orientation-events/device-orientation-events/info
Chrome : https://chrome.google.com/webstore/detail/sensors-for-chrome/bnoopapopgglfeecfncmjbdcjafpkoai

kushagra-gour's picture

Awesome article! Would there be a similar article for desktop mode apps in JavaScript also?

Add a Comment

Have a technical question? Visit our forums. Have site or software product issues? Contact support.