August 20, 2015 10:43 am

.NET Native – What it means for Universal Windows Platform (UWP) developers

This blog was written by Daniel Jacobson, Program Manager

What is .NET Native?

.NET Native is a precompilation technology for building Universal Windows apps in Visual Studio 2015. The .NET Native toolchain will compile your managed IL binaries into native binaries. Every managed (C# or VB) Universal Windows app will utilize this new technology. The applications are automatically compiled to native code before they reach consumer devices. If you’d like to dive deeper in how it works, I highly recommend reading more on it at MSDN.

How does .NET Native impact me and my app?

Your mileage likely will vary, but for most cases your app will start up faster, perform better, and consume fewer system resources.

  • Up to 60% performance improvement on cold startup times
  • Up to 40% performance improvement on warm startup times
  • Less memory consumption of your app when compiled natively
  • No dependencies on the desktop .NET Runtime installed on the system
  • Since your app is compiled natively, you get the performance benefits associated with native code (think C++ performance)
  • You can still take advantage of the industry-leading C# or VB programming languages, and the tools associated with them
  • You can continue to use the comprehensive and consistent programming model available with .NET– with extensive APIs to write business logic, built-in memory management, and exception handling.

You get the best of both worlds, managed development experience with C++ performance. How cool is that?

Debug versus Release compile configuration differences

.NET Native compilation is a complex process, and that makes it a little slower when compared to classic .NET compilation. The benefits mentioned above come at a cost of compilation time. You could choose to compile natively every time you want to run your app, but you’d be spending more time waiting for the build to finish. The Visual Studio tooling is designed to address this and create the smoothest possible developer experience.

When you build and run in “Debug” configuration, you are running IL code against the CoreCLR packaged within your application. The .NET system assemblies are packaged alongside your application code, and your application takes a dependency on the Microsoft.NET.CoreRuntime (CoreCLR) package.

This means you get the best development experience possible – fast compilation and deployment, rich debugging and diagnostics, and all of the other tools you are accustomed to with .NET development.

When you switch to “Release” mode, by default your app utilizes the .NET Native toolchain. Since the package is compiled to native binaries, the package does not need to contain the .NET framework libraries. In addition, the package is dependent on the latest installed .NET Native runtime as opposed to the CoreCLR package. The .NET Native runtime on the device will always be compatible with your application package.

Local native compilation via the “Release” configuration will enable testing your application in an environment that is similar to what your customers will experience. It is important to test this on a regular basis as you proceed with development.

A good rule of thumb is to test your app this way periodically throughout development to make sure you identify and correct any issues that may come from the .NET Native compiler. There should be no issues in the majority of cases; however, there are still a few things that don’t play so nicely with .NET Native. Four+ dimensional arrays are one such example. Ultimately, your customers will be getting the .NET Native compiled version of your application, so it is always a good idea to test that version throughout development and before shipping.

In addition to making sure you test with .NET Native compilation, you may also notice that the AnyCPU build configuration has disappeared. With .NET Native brought into the mix, AnyCPU is no longer a valid build configuration because native compilation is architecture dependent. An additional consequence of this is that when you package your application, you should select all three architecture configurations (x86, x64 and ARM) to make sure your application is applicable to as many devices as possible. This is the Universal Windows Platform after all. By default, Visual Studio will guide you to this as shown in the diagram below.

1_DotNetNativeCreateAppPackages
Figure 1 – All three architectures are selected by default

With that said, you can still build AnyCPU libraries and DLLs to be referenced in your UWP app. These components will be compiled to architecture specific binaries based on the configuration of the project (.appx) consuming it.

The last substantial change to your workflow as a result of .NET Native is how you create a store acceptable package. One great feature of .NET Native is that the compiler is capable of being hosted in the cloud. When you build your Store package in Visual Studio, two packages are created – one .appxupload and one “test” .appx for sideloading. The .appxupload contains the MSIL binaries as well as an explicit reference to the version of the .NET Native toolchain your app consumes (referenced in the AppxManifest.xml). This package then goes to the Store and is compiled using the exact same version of the .NET Native toolchain. Since the compiler is cloud hosted, it can be iterated to fix bugs without you having to recompile your app locally.

2__DotNetNativePackagesInExplorer
Figure 2 – The .appxupload goes to the store; the Test folder contains the sideloading appx package

This has two consequential changes to the developer workflow. The first is that you as a developer no longer have access to the revision number of your application package (the fourth one). The Store reserves this number as a way to iterate on the app package if for any reason the package is recompiled in the cloud. Don’t worry though, you still have control of the other three numbers.

The second is that you have to be careful about which package you upload to the Store. Since the Store does the native compilation for you, you cannot upload the native binaries generated by the local .NET Native compiler. The Visual Studio workflow will guide you through this process so you select the right package.

3__DotNetNativeCreatePackageForStore
Figure 3 – Select “Yes” to upload to the Store

When you use the app packaging wizard to create your packages, you should make sure to select “Yes” when Visual Studio prompts you to create a package to upload to the Store. I also recommend selecting “Always” for the “Generate app bundle” option as this will ultimately result in a single .appxupload file that will be ready for upload. For full guidance on creating a Store package, you can take a look at Packaging Universal Windows apps for Windows 10.

To summarize, the main changes to your workflow as a result of .NET Native are:

  • Test your application using the “Release” configuration regularly
  • Make sure to leave your revision package number as “0” – Visual Studio won’t let you change this, but make sure you don’t change it in a text editor
  • Only upload the .appxupload generated on package creation to the Store – if you upload the UWP .appx, the store will reject it with errors

Some other tips for utilizing .NET Native

If you find any issues that you suspect are caused by .NET Native, there is a technique you can use to help debug the issue. Release configurations by default optimize the code which loses some artifacts used for debugging. As a result, trying to debug a Release configuration can result in some issues. What you can do instead is to create a custom configuration and enable the .NET Native toolchain for that configuration. Make sure to not optimize code. More details about this can be found here.

Now that you know how to debug issues, wouldn’t it be better if you could avoid them from the get-go? The Microsoft.NETNative.Analyzer can be installed in your application via NuGet. From the Package Manager Console, you can install the package via the following command: “Install-Package Microsoft.NETNative.Analyzer”. At development time, this analyzer will give you warnings if your code is not compatible with the .NET Native compiler. There is a small section of the .NET surface that is not compatible, but for the majority of apps this will never be a problem.

If you are curious about the startup time improvements of your app from .NET Native, you can try measuring it for yourself.

Known issues and workarounds

There are a couple of things to keep in mind when using the Windows Application Certification Kit (WACK) to test your apps:

  1. When you run the WACK on a UWP app that did not go through this compilation process, you will get a not-so-trivial failure. It will look something like:
    • API ExecuteAssembly in uwphost.dll is not supported for this application type. App.exe calls this API.
    • API DllGetActivationFactory in uwphost.dll is not supported for this application type. App.exe has an export that forwards to this API.
    • API OpenSemaphore in ap-ms-win-core-synch-11-1-0.dll is not support for this application type. System.Threading.dll calls this API.
    • API CreateSemaphore in api-ms-win-core-kernel32-legacy-11-1-0.dll is not supported for this application type. System.Threading.dll calls this API.

    The fix is to make sure you are creating your packages properly, and running WACK on the right one. If you follow these packaging guidelines, you should never encounter this issue.

  2. .NET Native applications that use reflection may fail the Windows App Cert Kit (WACK) with a false reference to Windows.Networking.VpnTo fix this, in the rd.xml file in your solution explorer, add the following line and rebuild:
    <Namespace Name=”Windows.Networking.Vpn” Dynamic=”Excluded” Serialize=”Excluded” Browse=”Excluded” Activate=”Excluded” />

Closing thoughts

All Windows users will benefit from .NET Native. Managed apps in the Store will start and run faster. Developers will have the .NET development experience they are used to with Visual Studio, and customers get the performance boosts of native code. If you’d like to provide feedback, please reach out at UserVoice. If you have a bug to report, you can file it at Connect.

Updated August 20, 2015 12:28 pm

Join the conversation

    • @Alex, thank you for the feedback. Unfortunately F# is not currently supported with .NET native. The .NET Native team is monitoring feedback and this is something that has been expressed pretty frequently. They will reassess priorities in future releases.

    • I have a gut feeling this will never come to pass, especially not for winforms. There has not been another peep about it (and no promises to uphold earlier promises) on the .NN devs official blog in I believe a year’s time.

  1. “.NET Native compilation is a complex process, and that makes it a little slower when compared to classic .NET compilation”

    A _little_ slower??? That’s a joke right? As you said yourself “It is important to test this on a regular basis as you proceed with development”, we still need to frequently take this extreme overhead. Even the simplest blank UWP app takes almost 5 minutes to compiler with .NET Native. A C++ UWP app is way faster than this. There’s definitely room for lots of improvement here. The current state means we won’t be testing with the .net native toolchain as much as we should.

    • @Morten, we are aware of this issue and will continue to make improvements in future iterations of the compiler. I hope you can use the .NET Native analyzer as a tool to help you reduce the impact of this.

    • @Onur, thanks for the feedback. As I mentioned in an above comment, we’ve been hearing this from several channels. I’ll make sure your feedback makes it to the right folks and they will reassess this in the future.

  2. Does this also mean that using a code obfuscation tool is not necessary for Universal Windows apps? Can I trust that my app really gets compiled into native code always or are there some exceptions?

    • @Markku, that is correct. Your managed projects will be obfuscated much better with .NET Native. The binaries that the end customer gets will always be native.

      • I was a kind of disappointed to read this reply. The one factual statement is that all universal assemblies will be delivered to devices in a native format. The statement that “managed projects will be obfuscated much better with .NET Native” is nonsensical. Much better obfuscated than what? Better than managed assemblies with no obfuscation? Certainly. Better than the renaming transforms available in the free Community Edition of Dotfuscator? Hard to say since Dotfuscator CE doesn’t support universal apps (yet) but this may also turn out to be true.

        …but the portfolio of obfuscation transforms available commercially are more diverse than simple renaming and are designed to manage an equally diverse spectrum of risks.

        Will .NET native binaries
        – provide cross assembly renaming to support consistent renaming across dependent components that call one another (via API libraries) that may be developed at different times or between device and cloud, …)? The scenarios here alone are numerous (and might even include Java!).
        – include control flow to break programmatic reverse engineering versus human inspection? – we know that this will be a thing – as it already is for objective C.
        – support tamper detection and defense?
        – detect runtime issues (like running on developer devices, in a simulator…)

        There are some organizations that don’t need to obfuscate at all – even with today’s managed assemblies – simply because the potential risks for them do not justify the effort. Will this group of organizations expand with the added effort that will be required to reverse engineer .NET Binary apps? Most definitely. …but will there be organizations whose risks (that often include more than IP theft) still need to include app hardening controls as one of the “layers” in their app risk management framework – even though their universal apps are now .NET native? Absolutely… The need to continuously assess application risk first – and THEN map risk management controls (technical and/or process) to manage those risks will never go away – no matter what technology “the good guys” may deliver. Risk can only be managed – never transferred .

        • for the life of me i can’t see how to correct the typo in the first sentence – “I was a king of disappointed” should read “I was kind of disappointed” – ….

        • @sebastian holst, while all obfuscated assemblies can be technically reversed to a readable .NET code, you **absolutely** can’t reverse native code to C#/.NET code. So yes, I second Daniel Jacobson that obviously it is much better.

          About some of your points:
          – There is almost no point of cross assembly renaming, as .NETNative is merging all assemblies into a single exe, all symbols are squashed there. Metadatas may still be there, but you can’t do much with them, as they don’t point to anykind of IL code.
          – I guess you know how much a simple async/await code is already obfuscated at the IL level? Guess what, the native code generated by this will be a lot more obfuscated. So simply using some async/await/yield return in your code in some critical paths with .NETNative and you already have a control flow obfuscated at a level much above what .NET obfuscators are able to do.

          Of course, it doesn’t mean that a .NETNative application is protected against piracy or reverse engineering. But the same apply to almost any kind of software, unless you are also the owner of the hardware, but that’s a different story…

          • Yes, if the goal is solely to get back to compilable C# code – .NET Native will be more difficult than unwinding control flow and renaming – agreed.
            …but .NET Native is targeting performance optimization – not security – so (for example)
            … one would not expect to see string encryption happen inside the .NET Native generation process (and sometimes that is all a bad actor is trying to look at)
            …also none of this addresses the detective responses (triggering behaviors when an app is tampered with, run inside a debugger, on a jail broken device, etc.)
            … and assemblies CANNOT always be merged (when they run on different devices/tiers, are developed at different times by different teams, include libraries that are distributed across multiple dev organizations – that may not even be part of the same org) and in these cases cross assembly renaming will continue to be relevant.

            Perhaps we just need to agree to disagree – but I thought my position was pretty reasonable – everyone should first assess what risks matter to them (not a technical metric) and then take appropriate steps to mitigate ONLY those risks – and for many (but not all) who develop standalone universal apps distributed through a MSFT marketplace – the .NET Native process will have the added benefit of eliminating the need for a commercial obfuscator. …BUT, I know of many scenarios that will not fit neatly into this construct.

            PS as a “fun fact” – PreEmptive’s first obfuscation product was for Java (it pre-dates the existence of .NET) and is (still) called DashO (“-o” is the “optimize” command for Java). Yes, the first obfuscator began it’s life as an optimization tool in the 1990’s – and so the connection between optimization and obfuscation is well-established – but they will never be synonymous. PPS a large part of why MSFT asked us to build the .NET obfuscator in 2002 was because (prior to .NET) MSFT was a Java obfuscation client of ours. Be safe out there 🙂

  3. If you know that performance, memory management of .NET Native is much better then why .NET Native is not available for WinForm and other Windows Applications?

  4. Hi, recently i doing a little crazy stuff with unity. so what I do is copy a .NET assemblies (System.Management) to unity Plugins folder. then, I trying to test it within my project using this code:
    —–
    ManagementObjectSearcher searcher = new ManagementObjectSearcher (
    WMINamespace,
    “SELECT ” + Member + ” FROM ” + WMIClass + ” ” + AddQuery);
    —–
    but suddenly, when i try that script, unity crashed even when i debug my script from MonoDevelop. even when i build the project, unity fail to compile the .NET assembly inside Plugins folder.

    so is there anybody have tried this crazy stuff? cause as far as i know that Unity are using mono Assemblies, and from mono documentation says, System.Management are not included in their assemblies.

  5. I can’t compile my project in Release mode to publish to the Windows Store. I get the following error:

    Warning : DEP0810 : This app references Microsoft.NET.Native.Runtime.1.1, version 1.0.0.0, found in your SDK, but you have a higher version of Microsoft.NET.Native.Runtime.1.1 installed on the target machine, 1.1.23231.0. If you continue to run this application, it will run against the currently installed version, Microsoft.NET.Native.Runtime.1.1, version 1.1.23231.0. Consider updating your SDK to match the version of Microsoft.NET.Native.Runtime.1.1 that is installed. I am using a SP2, Windows 10, VS2015 Version 14.023107.0.

    I’ve tried downloading the latest Microsoft.Net.Native.Runtime in the Windows Store. I see the package in the Downloads and Updates section, when I try to install it package, I can see it downloading and installing, and completing. However it did not install. The package shows up again when I check for updates.

    I have the following Microsoft Windows updates on my system:
    KB3074686, KB3074678, KB3081448, KB3081449, KB3081452, KB3081444, KB3081441, KB3081438, KB3081436, KB3087916, KB3081424, KB3074683

    Any help will be appreciated. Thanks!

  6. This also means that one has to be VERY careful with generics. A simple code like this will cause runtime exception:

    var t = typeof(MyGeneric);

    foreach (var myg in new[] { typeof(int), typeof(long) }.Select(type => t.MakeGenericType(type))) {

    Naturally any code that generates IL at runtime will fail as well. One step forward (and backward) for speed and many steps backward…

  7. Is Behaviors SDK (XAML) supported by .NET Native? When I’m compiling it with .net native it generates some exceptions and does not work properly in runtime.

    • Hi Beka,

      This is an issue we are aware of and are working to fix. In the meantime, you can work around this by adding the following your default.rd.xml file:

      Instead of Windows.UI.Xaml.Shapes.Rectangle, use the typeName that you are using.

      • Typing the code here doesn’t work (formatting issues). Email me at dajaco at Microsoft dot com to get unblocked.

  8. Hello Daniel,

    I have the same problem as “Khanh Hoang”. When I compile my Store App in Release mode with .NET Native I get a warning: DEP0810 : This app references Microsoft.NET.Native.Runtime.1.1, version 1.0.0.0, found in your SDK, but you have a higher version of Microsoft.NET.Native.Runtime.1.1 installed on the target machine, 1.1.23231.0. If you continue to run this application, it will run against the currently installed version, Microsoft.NET.Native.Runtime.1.1, version 1.1.23231.0. Consider updating your SDK to match the version of Microsoft.NET.Native.Runtime.1.1 that is installed

    After that if I start debugging the app it crashes directly during the splash screen. Even if I just have an empty application with only a MainPage and a simple TextBlock. The following message in a dialog and output window:
    An issue in the App1.exe process caused it to fail to activate. This process exited with a native exception.
    The program ‘[2768] App1.exe’ has exited with code -1073741701 (0xc000007b).
    Activation of the Windows Store app ’85af5026-3a84-467e-a725-997e43606a43_nx1ad5fdtp86t!App’ failed with error ‘The app didn’t start’.

    After some further investigation it seems that the app crashes only when running with debugger. If I do “Start without Debugging” the app does launch.

    I am using Windows 10 / VS 2015 Pro 14.0.23107.0.

    Of course I want to run the app in the debugger. Can you please investigate and help ? How do I update the SDK to match .NET Native ?

    Also in the past I was able to run .NET Native release builds of store apps on this same machine.

    Thanks,
    Jeroen

    • Hi Jeroen,

      Can you send this to me in an email with specific repro steps and your environment information? Specifically, I’d like your OS version, VS version, Win10Tools version, and if you had any prerelease VS binaries installed previously.

      Message me at dajaco at Microsoft dot com and I’ll get the right people involved.

      Sincerely,
      Daniel

      • Hello Daniel,
        The problem has been solved but I did not change anything. But I did see a .NET Native update in the Windows Store being installed, so my guess is that this update solved the problem.
        I am a little bit worried because I get the feeling these store updates can mess things up. Also I cannot find any history of these updates on my Machine. Can you give any information on how this works ?
        Regards
        Jeroen

  9. You should really get this to work on all standard .NET languages before releasing it. Missing out on F# is not really acceptable.

  10. I wonder if a c# windows runtime component library will be converted to native code. The article just mentioned about the native code for windows store app (.exe). I have a universal windows store app that consists of a UWP exe and a UWP windows runtime component. I wonder if my c# component library be compiled to native code. Thanks.

  11. Well all well and good in theory but really poor in practice. We have converted our fast and fluid Windows 8 app to Windows 10 and now found it is so slow we cannot release it. The XAML seems really slow at displaying (ie screen starts) compared with 8. Also the build time is just stupid when in release. We go from 50mb and a few seconds of build in debug to 550mb and several MINUTES build time in release.

    I know for sure I much preferred the ease and speed of Windows 8 apps and also know we will never do another Windows app (8 or 10). So bad an experience all round.

    • As an update :

      Build in debug, make into store app and install on device. All seems good and fluid, screens open quickly. App fully functional. Uninstall

      Build in release, make into stores app (waits for ages at this point) and install on device. All is slow and sluggish. Screens take 3 seconds to appear.

      So after massive build time get a slower app then debug….doh!

    • A solution. In release mode in the project configuration – build tab. Uncheck the Compile with >Net native Tool Chain. Then all speedy on build and device.

      • We have the exact same problem. We can’t release because of the horrible performance with .Net Native. As I understand it you can’t circumevent this by unchecking the .Net Native toolchain since it is a prerequesite for the store certification. Did you find another solution?

  12. So is there a way to NOT use net Native on Windows 10 store apps? No emit; horribly broken reflection; LINQ Expression that are interpreted!!?? My app doesn’t survive this. WIll there be a non- .net Native for Windows store at some point, or should I just give up on this platform?