Scott Hanselman

How to call WinRT APIs in Windows 8 from C# Desktop Applications - WinRT Diagram

October 12, 2012 Comment on this post [28] Posted in Win8 | Windows Client
Sponsored By

I was trying to access some of the sensors that are built into this Intel Ultrabook that runs Windows 8. However, while there's support for Location Sensors built into the .NET 4 libraries on Windows 7 and up, I want to access the complete Sensor and Location Platform that is built into Windows 8 itself. Those APIs are available via COM and I could call them via COM, but calling them via the WinRT layer is so much nicer. Plus, this is kind of why WinRT exists.

This got me thinking about WinRT and what it means. I did a podcast a few months ago that really cleared things up but I've always found all the various diagrams that attempted to explain how things fit together to be WAY TOO COMPLEX.

DISCLAIMER: All diagrams are, by their nature, oversimplifications. I work on Web Stuff, not Windows Stuff, so this is all my opinion and conjecture, done on my own time. I'm not in the Windows org, I'm just a dude trying to write an app for babies.

I figure it can't be as complicated as all these diagrams. I drew this to help myself understand.

WinRT Diagram

Just like the C Language has the C Runtime that provides a bunch of supporting functions and defines a calling convention for them, so the Windows Runtime (WinRT) does for Windows and its languages. These APIs and runtime includes metadata about calling conventions that make WinRT APIs easier to call than COM.

See how in the diagram I can call any API from the .NET CLR? In the case of the Sensors APIs I want to call, while they are ultimately Win32 APIs or COM APIs, I would like to call them using the highest level calling convention available and that's the very friendly Windows RT ones.

Calling WinRT APIs from C# Desktop Applications

I like to test things using small Console Apps, but those aren't "Windows Store Applications," so am I allowed to call WinRT APIs from my Desktop or Console application?

Sure. There's actually a section of the MSDN Documentation that lists out all the WinRT APIs for Windows 8 that are able to be called from the Desktop. I can specifically check the LightSensor class itself within the documentation and make sure it's allowed to be called from Desktop applications.

LightSensor is allowed to be called from Desktop Apps

There isn't super-clear but there IS documentation on how to add WinRT references to non-Windows Store applications.

Adding a Reference to WinRT from a Desktop App

The docs say, somewhat obscurely:

In the desktop projects, the Core tab doesn’t appear by default. The user can choose to code against the Windows Runtime by opening the shortcut menu for the project node, choosing Unload Project, adding the following snippet, opening the shortcut menu for the project node again, and then choosing Reload Project. Now, when the user invokes the Reference Manager dialog box from the project, the Core tab will appear.

   <propertygroup>
    <targetplatformversion>8.0</targetplatformversion>
  </propertygroup>

I'll make a .NET 4.5 C# Console Application. I'll edit the .csproj and add the TargetPlatformVersion line. I'll select Add Reference from the context menu on the References node of Solution Explorer.

Windows Core References

I'll add a little code to check the status of the Light Sensor on my laptop:

LightSensor light = LightSensor.GetDefault();
if (light != null)
{
uint minReportInterval = light.MinimumReportInterval;
uint reportInterval = minReportInterval > 16 ? minReportInterval : 16;
light.ReportInterval = reportInterval;

light.ReadingChanged += light_ReadingChanged; //event hander
}

However, when I compile the app, I get an error on the line where I'm trying to hook up an event handler. The "+=" language sugar for adding a multicast delegate isn't working.

Error    1    Property, indexer, or event 
'Windows.Devices.Sensors.LightSensor.ReadingChanged'
is not supported by the language; try directly calling accessor
methods 'Windows.Devices.Sensors.LightSensor.add_ReadingChanged
(Windows.Foundation.TypedEventHandler
Windows.Devices.Sensors.LightSensorReadingChangedEventArgs>)'
or 'Windows.Devices.Sensors.LightSensor.remove_ReadingChanged
(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken)'

To fix this and get the appropriate assemblies loaded within my application support calling WinRT from my Desktop Application I need to add a reference to System.Runtime and System.Runtime.InteropServices.WindowsRuntime.dll. It's in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5 on my system.

System.Runtime.InteropServices.WindowsRuntime.dll in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5

Now my app compiles. I'll even change out the delegate and make it a Anders lambda because that's fancy.

light.ReadingChanged += (s, a) =>
{
Console.WriteLine(String.Format("There was light! {0}", a.Reading.IlluminanceInLux));
};

Now I can run my little console app, sense some light and check it out in action. Here's a screenshot showing the results of me shining a light at my laptop. You can see the Ambient LightSensor picks it up and outputs to the Console.

The ambient light sensor reacting

While the tooling to make non-Windows Store applications call Windows RT applications is a little manual within Visual Studio right now, the underlying ability and runtime have work very nicely for me. Hopefully these few manual setups will turn into a checkbox at some point.

It's also nice to see the MSDN documentation includes the details about which APIs actually can be called from the Desktop and which can be called from Windows Store apps.


This week's sponsor: Your Idea. Your App. 30 Days. Begin your 30-day journey to creating a Windows Store app or game for Windows 8 or Windows Phone today.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
October 12, 2012 10:00
The "make it a Anders lambda" part was hilarious ;)

Great info Scott. Thanks for all the free inspiration & energy you spread through your blog and presentations.
October 12, 2012 10:49
Very good info, thanks Scott!
October 12, 2012 11:09
http://www.codeproject.com/Articles/457335/How-to-call-WinRT-APIs-from-NET-desktop-apps
October 12, 2012 11:35
Amazing! Brilliant! Thanks!
October 12, 2012 12:12
Wow! Thanks, Scott (and thanks for the other link, André). I'd completely got the idea that you weren't able to use WinRT from the desktop at all.

Unfortunately the MSDN docs seem to be inconsistent. The list of "usable APIs" you linked to at MSDN seems to contain loads of WinRT classes that say "Applies to: Windows Store apps only" when you follow the link. <sigh>

Don't worry, I'm not complaining to you (it's nothing to do with you, right?)! I've sent some feedback to MSDN from the page. I don't think can be the only one, as it currently says "15 out of 79 rated this helpful"!
October 12, 2012 12:39
Nice :-) !
Thanks
October 12, 2012 15:00
Thanks for the tip about adding references to WinRT components from non-WinRT apps.

That diagram seems to suggest that the WinRT API is a layer of abstraction stacked on top of Win32. Was that the intent? Because as I understand it WinRT is stacked directly on top of the kernel and there's nothing in-between the two or am I missing it completely?
October 12, 2012 16:16
That was just what I was looking for Scott. Thank you so much. When Microsoft lost the ability to say "Metro", I think it really hurt the ability to Google for good help (and Bing doesn't help either). When I search for "desktop" and WinRT I usually get code for apps formerly known as Metro. The differentiation between Windows Store and Windows Desktop is very small. For me, this problem manifested itself when trying to search on just this topic. I saw that the API I wanted was available but I couldn't figure out how to access it. Now I know. As usual, this was a very relevant and helpful post. Thanks again.
October 12, 2012 16:32
Thanks! Is there any way of targetting, say, Win 7 but accessing WinRT features if they're available?
October 12, 2012 18:22
Excellent, now how do I call the beautiful facebook file/photo pickers from desktop?
October 12, 2012 18:47
This blog post states that it is also possible to create WinRT-based windowed XAML applications - despite XAML is not listed at a "Desktop-supported" API. Intriguing, uh ?
October 12, 2012 18:59
This is great! Thanks for sharing Scott.
October 12, 2012 22:33
i've used winRT APIs from PowerShell successfully, however have not managed to work out how to instantiate and call the full range of them.
October 13, 2012 22:45
I may be wrong, but CLR was implemented using COM APIs.

Here is my wondering question: what's the fundamental technical reason why CLR/.NET Framework (Silverlight - slightly variant CLR) is not suitable to write Windows Store Apps (Windows 8 App)?

In other words, why MS create WinRT on Windows 8?
October 13, 2012 23:35
I'm listening to your podcast: Understanding WinRT and Windows 8 for .NET Programmers.

Here is my own understanding for my own question :-)

Looks like WinRT is replacing WIN32 APIs/COM APIs. RT is referring to the runtime library (APIs), just like c runtime library, is not equivalent of CLR runt time - which is virtual machine that provides JIT, Memory management, threading, etc.

WinRT is library technology to enable multiple languages clients, like JavaScript, C++, .NET Language with metadata for the APIs, and the Metadata is same .NET metadata format!

WinRT is cross programming languages; CLR is cross OS platform, at least the Silverlight CLR was trying to do.
So pity MS is stopping Silverlight/CLR crossing platform effort, because losing mobile and tablet market to iOS.

So the real cross OS platform is JavaScript Interpreter (Runtime) - making JavaScript is in fact everywhere - mobile, tablet, desktop, any client, and servers.

No wondering Anders Hejlsberg is working on TypeScript, not C#/.NET Framework innovation.

The purpose of WinRT is refactoring/optimizing API Libraries (smaller assemblies) for Mobile and Tablet Application development – This does make sense.

Thanks a lot for all your blogs and podcasts!
October 15, 2012 19:15
Thanks Scott, here is hope for the WinRT checkbox too - please keep pushing your colleagues.

When seeing those quick code samples containing "lambda event handlers" I always ask myself if it is useful to put this memory leaking practice in the mind of the reader...?

See http://stackoverflow.com/a/16484

What do you think?
Tom
October 17, 2012 8:49
After adding the TargetPlatformVersion into the cproj file and a reference to the Windows.winmd, I receive the following error after attempting to publish...

The "ResolveManifestFiles" task failed unexpectedly.
System.ArgumentException: Value does not fall within the expected range.

Afterwards, it will produce the same error when attempting a simple solution build.

Can you point me to what might be causing the problem? This occurs whether the project is a console or WPF project.

Thanks!
Ed

Ed
October 18, 2012 20:54
I am Sorry to ask this here, but you are the best person to answer this question, I will appreciate if you can help me with this. THank you.

I have been hearing from people that asp.net mvc has full control over traditional asp.net webforms and that is best reason to do programming in asp.net mvc.


Based on this my Question
1) I believe Ado.Net has more/full control over ORM then what is the reason of using ORM, when we believe in having full control of what we are doing...
2) One obvious advantage i can see with ORM is we can switch database (Eg: Oracle to SQL Server) without changing anything in code, but argument is this is big decision and I don't think anyone keep changing their databases so frequently than I don't think it is truly an advantage.
3) RAD development with ORM, but since we want full control it is worth spending time on doing things manually and with defined strategy of doing this we can develop things faster.
4) I have seen in past that Microsoft keep on Recommending so many things and after sometime it comes from microsoft itself that, that is not recommended to use and you should use something else... Is it Microsoft Sales strategy.

Asp.net MVC vs Asp.net Web Form
1) With release of .Net 4.0 we can do almost all the things we can do in asp.net mvc and on top of it we have advantage of RAD when we are doing it with asp.net web forms than what is fun of using asp.net mvc architecture.

- For ViewState, we can turn it off
- For Having full control on HTML, we can generate HTML by dynamically creating controls (By this method we can achieve full control on HTML)
- We have clean seperation of UI vs Code, since in Web Forms we are not using any Code logic
- We have Routing for web forms too so that we can have SEO Friendly URL
- I have also seen that performance is little degraded with asp.net mvc then doing coding with asp.net web forms.
- MVC is just architecture which we can also do in Web Forms
- We can also be TDD compliant with Web Forms
- Almost all things which asp.net mvc have + advantage of RAD and simplicity of web forms than what is reason on switching to asp.net mvc?

I truly don't have any convincing answer which can please me towards this new technology... I have seen lot of people run around the buzz which Microsoft creates, but i truly don't see any added value in this...

To all the experts, could you please point some light and help me in understanding value of investing time and money in this new technologies.
October 22, 2012 21:45
Give pocket a try, http://getpocket.com/ formatly "read it later".
Dev
October 23, 2012 1:39
That's some helpful stuff there. I've been wondering how those two things interact.

Thanks.
October 25, 2012 3:01
Scott, thank you for this :)
October 28, 2012 16:45
I have been hearing from people that asp.net mvc has full control over traditional asp.net webforms and that is best reason to do programming in asp.net mvc.
January 10, 2013 11:00
Thanks ,Scott
January 10, 2013 16:48
This is all very good but I dont see the point! By using WinRT assemblies in your application you are rather tying yourself to Windows 8. Having a desktop application that can only run on Windows 8 is somewhat limiting!
April 06, 2013 14:53
velllll done
April 18, 2013 19:23
Thanks for this - I've spent several hours today dealing with this kind of thing, progress was slow but I did get my stuff building - until I tried to use the ConnectionReceived event in the StreamSocketListener.

Scott: How did you know that adding a ref to the Interop assembly would cause the event to compile cleanly?

James Millar - one thing you need to consider is the desire to write portable C# code libraries that can run on desktop, store and phone 8.

Thanks for a helpful post!

September 30, 2013 20:16
Thanks for this - I was beginning to think it wasn't possible to use them from .NET desktop apps. Am I right in thinking that you can only use WinRT classes/methods from an app that is targeting .NET 4.5 though? Also presumably you can't do it from VS 2010?
November 18, 2013 9:06
Hello, i try use this on a desktop appz, windows 8 x86
http://code.msdn.microsoft.com/windowsapps/Edge-gesture-invocation-76a474dd

Know some way to access to edge gestures from desktop appz and not stroe appz?

I work i c#

Really apreciated any info

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.