Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a F# PCL for Universal apps (a.k.a. Store Apps or Windows apps or WinRT apps)

Since Visual Studio 2013 Update 2, it is possible to create Portable Class Libraries (PCLs) that can reference Windows Runtime types (which was not possible before) as long as they only target Windows 8.1 and Windows Phone 8.1 and no other targets.

I tried this in C# by adding a C# Class Library (Portable for Universal Apps) and it works, which means that you can consume and produce Windows Runtime types as if the project was a Windows App or Windows Runtime Component.

Since F# also supports PCLs and Windows 8.1 and Windows Phone 8.1 are supported targets, I would like to achieve the same with F# PCLs (if possible). While Visual Studio 2013 Update 4 does not offer creating F# PCLs that only target Windows 8.1 and Windows Phone 8.1, it is possible to modify the .fsproj file of an F# PCL to match the .csproj file of a C# PCL with those targets that was created with Visual Studio. This requires changing the XML elements to the following:

<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile32</TargetFrameworkProfile>

and adding the following to an <ItemGroup>

<TargetPlatform Include="WindowsPhoneApp, Version=8.1" />
<TargetPlatform Include="Windows, Version=8.1" />

After these changes, I was able to consume and produce Windows Runtime types in the F# PCL as in the C# PCL (without complaints from Visual Studio in the F# PCL or C# (Universal) Windows App), but when I actually run the (Universal) Windows App I get the following exception when a function that uses Windows Runtime types is called in the F# PCL from the C# (Universal) Windows App:

An exception of type 'System.IO.FileNotFoundException' occurred in [application name].exe but was not handled in user code

Additional information: Could not load file or assembly 'Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

When I check the references in the Solution Explorer of Visual Studio, the C# PCL shows a reference named Windows, which is missing from the F# PCL. The Reference Properties of that reference look like this:

properties of Windows reference

I tried adding this reference manually to the .fsproj file of the F# PCL by adding

<Reference Include="C:\Program Files (x86)\Microsoft SDKs\Portable\v12.0\110C4FEFF2BA61C0746933A9ED6E248D\Windows.winmd" />

to an <ItemGroup>. After this, the reference does show up in the F# PCL in the Solution Explorer with the following Reference Properties:

enter image description here

but does not fix the problem. That is, I still get the same exception as before.

I also tried copying and pasting the Windows reference via the context menu of the Solution Explorer of Visual Studio, but it complains with an error message.

Do you know how to properly add the Windows reference to a F# PCL? This would be really awesome, because that would make it possible to write (Universal) Windows Apps almost entirely in F#! If you know for a fact that this is not possible, then could you please explain what is preventing this from being possible?

EDIT: improved formatting of exception message

like image 658
user3323923 Avatar asked Apr 29 '15 01:04

user3323923


1 Answers

You're making a portable class library. F# does not support windows store apps, so the only way you can use F# in such a situation is to call it from C#. If you manage to succeed, you'll be the first of anyone.

like image 78
phil Avatar answered Sep 22 '22 19:09

phil