Walkthrough: Using WinRT libraries from a Windows Desktop application

Summary

These are the steps for enabling WinRT libraries from within your Windows Desktop application. A more detailed walkthrough and explanation follows.

Steps

1) Editing your project file, add the platform target:

    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetPlatformVersion>8.0</TargetPlatformVersion>
</PropertyGroup>

2) Add the following references:

    <Reference Include=”Windows” />
<Reference Include=”System.Runtime” />
<Reference Include=”System.Runtime.InteropServices.WindowsRuntime” />
<Reference Include=”System.Runtime.WindowsRuntime” />

3) Load your project properties, and change the platform target from AnyCPU to x64 (or x86 if you’re on a 32 bit operating system).

Prerequisites / Limitations

  • You are obviously limited to WinRT-supported platforms: Windows 8 & 8.1, Windows Server 2012
  • Some of the WinRT libraries won’t work on the desktop platform, usually because they require a WinRT user interface. Pay attention to the MSDN docs which state whether they’re available for Desktop, but also feel free to experiment, as in some cases the docs are not accurate (for example, the Geolocation works on Desktop but the documentation states Windows Store apps only).

Overview

You might be surprised to know that WinRT can be used from Windows apps also, with a little bit of tweaking.

What is WinRT?

  • WinRT is not .NET or Win32, though it shares some similarities between both.
  • WinRT is an API over a new runtime, that supports platforms from Windows x86 to Windows Phone ARM.
  • WinRT is implemented in C++, but you can develop for it using C# and VB.NET.
  • Because the WinRT metadata is exposed as CLI metadata (in .WinMD files), you can reference and consume them from your CLR applications.

Why would you want to use WinRT?

Walk-through: Changing the Lock Screen

As a case study, we will look into changing the user lock screen to the Bing daily picture.

Prerequisites

  • You will need to be reasonably comfortable with async code, as most of the API is exposed via Tasks.

Getting started

Create a new Windows C# command line application:

clip_image001[4]

I’ll call mine WinRTTest.

Referencing a WinRT library: Take 1

Now let’s try adding a reference to a WinRT library.

Go to Add Reference, and choose Browse:

clip_image002[4]

Then hit the Browse button, and select C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral\Windows.winmd (or the 8.1 version) and click OK.

CLANG!

clip_image003[4]

Checking the documentation as instructed, we read this:

In the desktop projects, the Core subgroup doesn’t appear by default. You can add the Windows Runtime by opening the shortcut menu for the project node, choosing Unload Project, adding the following snippet, and re-opening the project (on the project node, choose Reload Project). When you invoke the Reference Manager dialog box, the Core subgroup appears.

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

From <http://msdn.microsoft.com/en-us/library/hh708954.aspx>

Great! So now we know we must specify our target platform as 8.0.

Preparing the Project File

First let’s edit the project file; right click on the project file and choose Unload Project then Edit Project File.

I’ll add the target platform property in the property group at the top of the project file:

  <PropertyGroup>
<Configuration Condition=” ‘$(Configuration)’ == ” “>Debug</Configuration>
<Platform Condition=” ‘$(Platform)’ == ” “>AnyCPU</Platform>
<ProjectGuid>{4725C47D-8877-47C8-BD56-134E656BFF09}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WinRTTest</RootNamespace>
<AssemblyName>WinRTTest</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetPlatformVersion>8.0</TargetPlatformVersion>
</PropertyGroup>

Referencing a WinRT Library: Take 2

Now reload the project and choose Add Reference… again. Suddenly, the Windows tab is available for us:

clip_image006[4]

Let’s tick Windows and click OK.

Now let’s start coding with the WinRT libraries.

Adding the HttpClient NuGet package for downloading the Bing picture

The HttpClient class will be a nice easy way for us to use the Bing Daily Picture service.

First, add a reference to the NuGet package for the HttpClient.

  1. In the Visual Studio menu, go to Tools > NuGet Package Manager > Package Manager Console
  2. Then type in the following command at the prompt:Install-Package Microsoft.AspNet.WebApi.Client
PM> Install-Package Microsoft.AspNet.WebApi.Client
Attempting to resolve dependency 'Newtonsoft.Json (≥ 6.0.4)'.
Installing 'Newtonsoft.Json 6.0.4'.
Successfully installed 'Newtonsoft.Json 6.0.4'.
Installing 'Microsoft.AspNet.WebApi.Client 5.2.2'.
You are downloading Microsoft.AspNet.WebApi.Client from Microsoft, the license agreement to which is available at http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device.
Successfully installed 'Microsoft.AspNet.WebApi.Client 5.2.2'.
Adding 'Newtonsoft.Json 6.0.4' to WinRTTest.
Successfully added 'Newtonsoft.Json 6.0.4' to WinRTTest.
Adding 'Microsoft.AspNet.WebApi.Client 5.2.2' to WinRTTest.
Successfully added 'Microsoft.AspNet.WebApi.Client 5.2.2' to WinRTTest.

So now we have our new references:

clip_image008[4]

The Code

Now, paste in the code below:

 

Note that we are hard-coded to get the 1080p version of the desktop, and there’s not much error handling. We’re keeping it nice and brief; getting the appropriate wallpaper size and error handling could be left as a future exercise.

David, your code sucks. It won’t compile.

I can’t argue with those statements:

1>------ Build started: Project: WinRTTest, Configuration: Debug Any CPU ------
1>C:\Projects\WinRTTest\WinRTTest\Program.cs(37,32,37,168): error CS4028: 'await' requires that the type 'Windows.Foundation.IAsyncOperation<Windows.Storage.StorageFile>' have a suitable GetAwaiter method. Are you missing a using directive for 'System'?
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

If you paid close attention to the MSDN docs earlier, it referred us to another page which states:

That said, your desktop app can’t consume much of anything from the Windows Runtime until you prepare your project with one essential reference. The Windows Runtime defines some standard classes and interfaces in System.Runtime, such as IEnumerable, that are used throughout the Windows Runtime libraries. By default, your managed desktop app won’t be able to find these types, and so you must manually reference System.Runtime before you can do anything meaningful with Windows Runtime classes.

From <http://msdn.microsoft.com/en-us/library/windows/apps/jj856306.aspx#consuming_standard_windows_runtime_types>

While we could browse around for files, I believe it’s actually less error prone and simpler to reference the assembly name in our project file, and let Visual Studio do the rest. It also means you can prepare your project for WinRT in one edit of the project file (see the summary at the top of the article).

Now the System.Runtime reference isn’t going to be enough for us, as the async support extensions are in the WindowsRuntime classes. So add the following:

    <Reference Include=”Windows” />
    <Reference Include=”System.Runtime” />
    <Reference Include=”System.Runtime.InteropServices.WindowsRuntime” />
    <Reference Include=”System.Runtime.WindowsRuntime” />
</ItemGroup>

Now we can compile!

Testing

So we run the app. The image comes down and is saved into our Pictures folder as LockScreen.jpg:

clip_image009[4]

But if you lock your machine by hitting Windows + L, our lock screen isn’t showing the changes.

Weirdly, it’s showing in the control panel though:

clip_image010[4]

Well after some trial and error myself, let’s change the target platform from AnyCPU to x64 (or x86 if you’re on a 32 bit machine):

clip_image011[4]

And it should suddenly work!

Now, it’s unclear why this is necessary (and why we see no errors, and the lock screen actually shows in the control panel). Frustratingly, I can’t troubleshoot the problem properly, as setting the platform target back to Any CPU suddenly continues to work also. There may be something else happening here; so I will update this article if an explanation ever comes to light.

Conclusion

Now you can play around with some of the interesting WinRT libraries from your desktop applications, as well as exciting new WinRT extensions such as the Microsoft OCR Library: http://blogs.windows.com/buildingapps/2014/09/18/microsoft-ocr-library-for-windows-runtime/

Using MSBuild property functions and inline tasks: Example doing performance calculations

The Problem

User RandDavis on Reddit asked a question about capturing elapsed time of tasks in MSBuild:

I’m using MSBuild 4.0 (I also have MSBuild.Community.Tasks available). Note that I’m new to the syntax involved. All I’m trying to do is this: store the current time to a property, run a process, and determine the time that has elapsed. I’ve managed to write System.DateTime.Now to a property, but I don’t know how to do a simple datediff or construct a TimeSpan, so that I can get at what I’m looking for. I’d be utterly shamed if I had to resort to string comparisons or writing a custom task.

Options

The good thing is that he’s using MSBuild 4.0, which means he can use any combination of property functions and inline tasks to achieve all he wants from within the MSBuild code, without having to compile and version custom MSBuild task assemblies, which can become a pain in the ass to move forwards with.

When benchmarking from .NET, the best practice is to use the Stopwatch class in System.Diagnostics. Using DateTime functions is the natural but more inaccurate and naive way to benchmark. Eric Lippert of C# compiler fame did a good series on benchmarking mistakes, with Stopwatch mentioned in part 2.

In MSBuild, you’re limited to what classes you can use for property functions, so this means we have to resort to using inline tasks if we want to use Stopwatch. And because MSBuild is an imperative, XML-based language, we can’t really use Stopwatch in the normal way (get an instance, start and stop it, etc).

Because Rand (I’m guessing that’s his name) doesn’t seem to require much precision, using DateTime might be more than enough, and it can also make for some simpler code.

Solution 1: Using property functions and DateTime ticks

So here’s the first example, using property functions and DateTime:

Interestingly, the Stopwatch uses DateTime Ticks if it can’t use high precision time. So this is likely as good as we’re going to get using DateTime. If we run the project using MSBuild, Notepad should pop up. We can leave it open for a bit, then close it down, and see what measurement we got:

C:\>"C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe" Test.DateTime.proj
Microsoft (R) Build Engine version 12.0.30501.0
[Microsoft .NET Framework, version 4.0.30319.18408]
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 19/07/2014 5:07:25 p.m..
Project "C:\Projects\Test.DateTime.proj" on node 1 (default targets).
Test:
Starting ticks: 635413432457421728
notepad
Elapsed time: 00:00:02.4999296
Done Building Project "C:\Projects\Test.DateTime.proj" (default targets).

Build succeeded.
0 Warning(s)
0 Error(s)

Time Elapsed 00:00:02.51

OK, seems fair enough! The code is quite simple too, and could be fine if we’re not needing much precision.

Solution 2: Using inline tasks and Stopwatch

OK, so how can we use inline tasks to leverage the power of the .NET framework?

Phew! Ok this code would be smaller and simpler if you removed some of my comments, and Microsoft had made some of the key methods and properties in the Stopwatch class available.

So here’s how that looks:

C:\Projects>"C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe" Test.StopWatch.proj
Microsoft (R) Build Engine version 12.0.30501.0
[Microsoft .NET Framework, version 4.0.30319.18408]
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 19/07/2014 5:52:59 p.m..
Project "C:\Projects\Test.StopWatch.proj" on node 1 (default targets).
Test:
  Starting timestamp: 5443820462687
  notepad
  Elapsed time: 00:00:02.7861944
Done Building Project "C:\Projects\Test.StopWatch.proj" (default targets).


Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:02.87

Would it be possible some way to return a Stopwatch object that could be started and stopped, as you would do in C# code? Possibly! But I think that wouldn’t fit well with the way MSBuild works.

Links:

Gist containing these two code files. You should change the extension back to .proj, being MSBuild projects. I need to keep the extension to .xml so Gist renders the code as XML.

References:

Deleting and purging items from Team Foundation Server

When you delete an item from TFS, it’s not actually permanently gone.

You can view deleted items by going to Tools > Options > Source Control > Visual Studio Team Foundation Server and checking the Show deleted items in the Source Control Explorer option:

image

You can then see folders and files that have been deleted, which allows you to right click on them to choose Undelete (or go to File > Source Control > Undelete).

It’s useful to show deleted items by default, but you may find that your source tree ends up a bit clogged with all the deleted files and folders.

You can purge items you want to delete permanently by using the TFS command-line tools.

TF.EXE is found with Visual Studio 2010 under C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDE for 64 bit machines, and C:Program FilesMicrosoft Visual Studio 10.0Common7IDE on 32 bit.

You might find it useful to add that path to your command line.

The commandlet you want to use is destroy, which tf.exe can give us info on:

C:WindowsSystem32>tf help destroy
TF - Team Foundation Version Control Tool, Version 10.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Destroys, or permanently deletes, version-controlled items from Team
Foundation version control.

tf destroy [/keephistory] itemspec1 [;versionspec]
[itemspec2...itemspecN] [/stopat:versionspec] [/preview]
[/startcleanup] [/noprompt] [/silent]
[/login:username,[password]]
[/collection:TeamProjectCollectionUrl]

Versionspec:
Date/Time         D"any .Net Framework-supported format"
or any of the date formats of the local machine
Changeset number  Cnnnnnn
Label             Llabelname
Latest version    T
Workspace         Wworkspacename;workspaceowner

To run the command, you have to specify the collection URL. An easy way to get this is open your Team Explorer window in Visual Studio (View > Team Explorer), select the root server node and look in the Properties window at the Url property.

Now you need the server name of the folder or file you want to purge. Locate the file or folder in the Source Control Explorer, right click and choose Properties…

The Server Name: value is what you want and can be selected and copied to the clipboard.

Now you can run the command:

tf destroy $/MyProject/Main/Bin /collection:http://servername:8080/tfs/myproject
Do you want to destroy $/MyProject/Main/Bin and all of its children? (Yes/No) y
Destroyed: $/MyProject/Main/Bin;X3601
Destroyed: $/MyProject/Main/Bin/Native;X3601

Now if you refresh in Solution Explorer, the purged items won’t even show up anymore.

Debugging MSBuild scripts

If you want to debug an MSBuild script from without Visual Studio, you need to use the /debug command line option.

The trick is that this option is not normally available; you need to set a registry key to enable it.

Enable the MSBuild Debugger

Under the HKLMSoftwareMicrosoftMSBuild4.0 key, create a string value called EnableDebugger with a value of “true”.

If you’re on a 64 bit system, you’ll also want to set the same value under the key HKLMSoftwareWow6432NodeMicrosoftMSBuild4.0.

Verify

If you then run msbuild /help, you should now see the documentation on the /debug switch:

/debug
                    Causes a debugger prompt to appear immediately so that
                    Visual Studio can be attached for you to debug the
                    MSBuild XML and any tasks and loggers it uses.

Debugging

Now you can pass the /debug option to MSBuild when running it. This will immediately break into the debugger, which will usually give you a prompt to select your JIT debugger:

image

The debug session will then start at the very top of the root MSBuild project file, and you can go from there.

You can set breakpoints in your MSBuild project files from within the IDE, and inspect the MSBuild variables using Locals and Watch.

Some more tips:

  • Your breakpoints may not show up to be hit yet until the project file they’re contained in actually loads. If you continue on, the project will get loaded and the breakpoint will get hit.
  • To prevent yourself breaking into framework code that you don’t have source for, you can check the Enable Just My Code (Managed only) option under Debug > Options and Settings > Debugging > General.
  • From the Immediate window to evaluate conditions using EvaluateCondition:
Immediate input: EvaluateCondition("'$(MyProperty)' == ''")
Immediate output: false
  • From the Immediate window you can evaluate expressions using EvaluateExpression (remember to escape slashes):
Immediate input: EvaluateExpression("C:\$(MyFolderName)")
Immediate output: C:MyFolder

Original article and full details (recommended reading) is here: http://blogs.msdn.com/b/visualstudio/archive/2010/07/06/debugging-msbuild-script-with-visual-studio.aspx

Error building project when referencing native assembly dependency in app.manifest

If you’re using an app.manifest, and defining assembly dependencies (i.e. for SxS / Side by side / Reg-free COM etc), you may encounter this error when you build the project:

Could not find file ‘AssemblyName, Version=x.x.x.x, PublicKeyToken=xxxxxxxxxxx, ProcessorArchitecture=x86, Type=win32′.

This is even when the native assembly is in place where the project can find it.

Example

For example, your app.manifest may contain this fragment:

<dependency>
<dependentAssembly>
<assemblyIdentity name=Native.Custom version=1.0.0.0 processorArchitecture=x86 type=win32 publicKeyToken=12345678/>
</dependentAssembly>
</dependency>

This manifest is available to the project, with the manifest file in the project directory or in a subdirectory called “Native.Custom”.

In this case, I have a sub directory called Native.Custom, which contains my Native.Custom.manifest file.

Solution

The problem may be because the ClickOnce manifests are being generated.

  1. Open your project file in a text editor (or right click it in Visual Studio and choose Edit Project)
  2. Find the  GenerateManifests element and set it to false:
  3. <GenerateManifests>false</GenerateManifests>
  4. Save the project and reload it.

Now you should hopefully be able to build.

Running .NET 2 Runtime applications under the .NET 4 Runtime

In some situations, you might want to run a .NET 2 Runtime application (.NET 2, 3.0, 3.5 SP1 etc) under the .NET 4 Runtime – without recompiling.

You can configure your app to execute under the .NET 4 runtime by adding these lines to the executable’s configuration file, under the root  configuration element:

<startup>
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>

Because the security framework has changed in the .NET 4 runtime, you will likely encounter some exceptions containing a message similar to:

System.NotSupportedException: This method explicitly uses CAS policy, which has been obsoleted by the .NET Framework. In order to enable CAS policy for compatibility reasons, please use the NetFx40_LegacySecurityPolicy configuration switch. Please see http://go.microsoft.com/fwlink/?LinkID=155570 for more information.

To avoid this, you  have to enable the legacy support by adding a runtime element :

<startup>
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<runtime>
  <NetFx40_LegacySecurityPolicy enabled="true"/>
</runtime>

If your application also uses mixed assemblies that contain both managed and native code (such as System.Data.SQLite.dll), you’ll see an error message like this:

Mixed mode assembly is built against version ‘v2.0.50727′ of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

You will need to enable the legacy activation to allow these to be loaded also:

<startup useLegacyV2RuntimeActivationPolicy="true">
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<runtime>
  <NetFx40_LegacySecurityPolicy enabled="true"/>
</runtime>

References

<startup> Element @ MSDN

<supportedRuntime> Element @ MSDN

<NetFx40_LegacySecurityPolicy> Element @ MSDN

<startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>
    <runtime>
        <NetFx40_LegacySecurityPolicy enabled="true"/>
    </runtime>

Dependency Property ReSharper Live Template

Dependency Property ReSharper Live Template

Don’t you love Dependency Properties?

After the ease of automatic properties though, dependency properties are a chore to define.

If you’ve got ReSharper (if not, why not?), I’ve got a simple Live Template you can use to create your dependency properties.

I’ve set it up to use the dp keyword.

Here it is in use. Typing dp first to pop up the template:

image

Hitting tab or enter will run the template, with the name macro already selected:

image

Type in the name of the property. This will set up the wrapper property with that name, and the dependency property’s name will be the name you chose, with “Property” added to the end.

For example, I type in MyCaption as the property name:

image

Hitting tab shifts me to the next macro, which is the type for the dependency property:

image

My property will be of type string, so typing that in will bring up string in the suggestions. Hitting tab will select this; hitting tab again will confirm this as my type, and select the next and last macro, the owner type:

image

This will automatically be set to the name of the containing type anyway, so you can normally leave this as is; hit tab one more time and you’re done.

HOW TO: Detect if the Visual C++ 2010 redistributable package is installed with WiX

As noted by Aaron Stebner, there is now a registry key you can search for to detect if the Visual C++ 2010 redistributable package is installed a machine, when installing your application.

There are 3 different (but very similar) registry keys for each of the 3 platform packages. Each key has a DWORD value called “Installed” with a value of 1.

  • HKLMSOFTWAREMicrosoftVisualStudio10.0VCVCRedistx86
  • HKLMSOFTWAREMicrosoftVisualStudio10.0VCVCRedistx64
  • HKLMSOFTWAREMicrosoftVisualStudio10.0VCVCRedistia64

Here’s an example of using this in WiX, detecting the presence of the x86 version of the redistributable:

<?xml version="1.0" encoding="utf-8"?>
    <Include>
        <!-- Visual C++ 2010 x86 -->
        <Property Id="HASVCPP2010">
        <RegistrySearch Id="HasVCPP2010Search" Root="HKLM" Key="SOFTWAREMicrosoftVisualStudio10.0VCVCRedistx86" Name="Installed" Type="raw" />
    </Property>    
    <Condition Message="This application requires Microsoft Visual C++ 2010 Redistributable Package (x86).">Installed OR (HASVCPP2010)</Condition>
</Include>

When someone runs your installer and they don’t have this package installed, they will get something like this message box when the installer initializes:

image

It’s a good idea to have a setup bootstrapper that automatically installs this package if it’s missing, but this WiX snippet is a good safe-guard for if someone directly runs your MSI.

Reference: http://blogs.msdn.com/b/astebner/archive/2010/05/05/10008146.aspx

HOW TO: Debug a Windows Installer custom action

Prerequisites:

  • Determine the name of the custom action you want to debug
  • Ensure you have the source code and debug symbols for your custom action

Steps

  1. Set the MsiBreak environment variable (user or system) to the name of the custom action. For example:

    Setx MsiBreak MyCustomActionName

  2. Run your installer
  3. At the point where your custom action is about to run, you should get this message box prompt:

  4. Now you can use Visual Studio or another debugger such as WinDBG to attach to the specified process.
  5. Click OK on the message box
  6. This should break into your debugger. This is a good time to set your breakpoints in your custom action code.
  7. When ready, run/continue the debug session.
  8. Your custom action should run and your breakpoint(s) will be hit.

References:

Debugging Custom Actions @ msdn.microsoft.com

Building Visual Studio 2010 Solutions in Team Foundation Server Build 2008

Visual Studio 2010 and Team Foundation Server 2010 have been out for a while. But what if you still have Team Foundation Server 2008 but want to build Visual Studio 2010 solutions on it?

You can do so by updating the Team Foundation Build Service configuration to use the latest version of MSBuild that comes with the .NET Framework 4.0.

  1. Open up %Program Files%Microsoft Visual Studio 9.0Common7IDEPrivateAssembliestfsbuildservice.exe.config in a text editor
  2. Find the MSBuildPath property, which will likely be empty, and enter the path to the .NET Framework 4.0 folder (C:WINDOWSMicrosoft.NETFrameworkv4.0.30319):
  3. Save the file
  4. Restart the  Visual Studio Team Foundation Build service

Reference: http://blogs.msdn.com/b/jimlamb/archive/2009/11/03/upgrading-tfs-2008-build-definitions-to-tfs-2010.aspx