How to call WinRT APIs in Windows 8 from C# Desktop Applications - WinRT Diagram
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.
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.
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.
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.
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.
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.
About Newsletter
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"!
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?
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?
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!
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?
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
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.
Thanks.
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!
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.
Anderslambda" part was hilarious ;)Great info Scott. Thanks for all the free inspiration & energy you spread through your blog and presentations.