Could not load file or assembly FSharp.Core with .net 4.5 / NDjango / Win8

The Problem

With today’s release of the RTM versions of Win8 and Visual Studio 2012 I, like many others no doubt, have formatted one of my machines, thrown the new bits on, and kicked the tyres with some code. Unfortunately, when I tried Nancy, everything build just fine, but running any tests involving NDjango (F# based) blew up with:

Could not load file or assembly ‘FSharp.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The system cannot find the file specified.

Or:

Could not load file or assembly ‘FSharp.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The system cannot find the file specified.

All this works perfectly fine with .net 4, and .net 4.5 is supposed to be backwards compatible, but in this case it seems not. I haven’t done much digging, but if a strongly named assembly changes version between .net 4 and .net 4.5 I would expect an assembly binding to be in place to stop this kind of thing from happening – it’s possible that NDjango is doing something odd, but still, if it works in 4, it should work in 4.5.

This may or may not be an issue on Win7 if you’ve had .net 4 installed previously.

The Solution

Luckily, it’s very simple to add your own binding redirects to get things up and running again. These can either go in the app.config/web.config of your application, or you can put it in the machine.config – I wouldn’t recommend the latter though, as you may end up with an “it works on my machine” situation a few months down the line.

Either way, this is the section you need to add, it maps both 2.0.0.0 and 4.0.0.0 to the version that ships with .net 4.5/Win8 :

<assemblyBinding  xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
        <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
        <bindingRedirect oldVersion="2.0.0.0" newVersion="4.3.0.0"/>
        <bindingRedirect oldVersion="4.0.0.0" newVersion="4.3.0.0"/>
    </dependentAssembly>
</assemblyBinding>

A simple solution, and maybe this will just affect me, but this blog post will at least stop me from pulling my own hair out if this happens again 🙂

WPF RichTextBox Subscript and Superscript Without Font Restrictions

Introduction

One of the most bizarre limitation of the WPF RichTextBox is its hit and miss support for subscript and superscript in text. Although you can set the style quite easily using appropriate command, in order for this property to actually alter the appearance of the text the font needs to be OpenType, and come with a Subscript/Superscript variant, which the vast majority of fonts do not. Obviously in a control that’s designed for user input, restricting what fonts can be used in this way is far from ideal.

An Alternative Approach

Having spent some time poking around inside RichTextBox I would strongly recommend that you don’t. Seriously. The code may well make you physically sick. In the past I have tried to use TextRange.ApplyPropertyValue, which takes a normal DependencyProperty, to attach my own property to a piece of text. You’d imagine this would be pretty straightforward, especially as attaching properties to other types is a fairly fundamental part of WPF, but unfortunately there’s a particularly lovely piece of code that checks to see if the DependencyProperty is on a predefined “allowed” list, and thows an exception if it isn’t. While this chunk of code scuppered my ideas in the past, it did provide a useful place to look for an alternative way to create Subscript and Superscript text.

One of the properties that we are “allowed” to apply to text is Inline.BaselineAlignmentProperty which takes its values from the BaselineAlignment enumeration which includes the following values:

  • Top
    A baseline that is aligned to the upper edge of the containing box.
  • Center
    A baseline that is aligned to the center of the containing box.
  • Bottom
    A baseline that is aligned at the lower edge of the containing box.
  • Baseline
    A baseline that is aligned at the actual baseline of the containing box.
  • TextTop
    A baseline that is aligned at the upper edge of the text baseline.
  • TextBottom
    A baseline that is aligned at the lower edge of the text baseline.
  • Subscript
    A baseline that is aligned at the subscript position of the containing box.
  • Superscript
    A baseline that is aligned at the superscript position of the containing box.

Subscript and Superscript look exactly like what we want, and amazingly, they actually work 🙂 To demonstrate the technique I’ve created two simple extension methods that toggle either Sub or Superscript on the selected text:

/// <summary>
/// Toggle Superscript for the currently selected text in a RichTextBox. Does not require the font to be OpenType or have a Superscript font style.
/// 
/// Doesn't attempt to change/restore the size of the font, just moves the baseline.
/// </summary>
/// <param name="richTextBox">RichTextBox with selected text</param>
public static void ToggleSelectionSuperscript(this RichTextBox richTextBox)
{
    var currentAlignment = richTextBox.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);

    BaselineAlignment newAlignment = ((BaselineAlignment)currentAlignment == BaselineAlignment.Superscript) ? BaselineAlignment.Baseline : BaselineAlignment.Superscript;
    richTextBox.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);
}

The code checks the current value of the BaselineAlignmentProperty and toggles the value as appropriate. I’ve made no attempt to adjust font size, or do anything clever, so it does look a little goofy, but it proves the concept. The demo application also includes the XAML content of the RichTextBox document so you can see exactly what content it’s producing:

RichTextBoxSubSuperscriptScreenshot

And that’s that, hope it helps someone out 🙂 You can grab the sample demo from the link below:

RichTextBoxSubSuperscript.zip

Surface SDK SP1 on Vista and Win7 x64

Introduction

This is a follow up post to Surface SDK on Vista x64 where we got the original Surface SDK working on the unsupported Vista X64. Last week Microsoft released Service Pack 1 of the SDK and there is an additional tweak that we need to get it going.

The original post was split into 3 sections:

  1. Patch the MSI and install
  2. Patch the Simulator and other files
  3. Configure our projects

Steps 2 and 3 haven’t changed with SP1 (we don’t need to “corflags” the new “stress” tool as it connects to the simulator rather than launching it), so jump over to the original post when you’ve got the SDK installed.

Prerequisites

  • Surface SDK SP1 (duh!)
  • Visual Studio 2008 (for corflags)
  • Orca (part of the Windows SDK or just search for it)
  • Administrator access to the Vista or Win7 box you’re installing onto.

Step 1 – The MSI

Firstly we need to use Orca to tweak the launch conditions of the MSI. Make sure you’ve installed all of the SDK pre-requisites first, then walk through the following:

  1. Install Orca (link above, or just search for it).
  2. Copy the SurfaceSDKWE.msi to somewhere on your hard disk, and make sure that it’s not Read Only.
  3. Right click on the MSI and choose Edit with Orca. This will trigger a UAC, but it’s software from Microsoft, so you should be ok to trust it 🙂
  4. Select “LaunchCondition” in the left hand list, then select “Install OR NOT VersionNT64” in the right hand list (see below).
    Remove Launch Condition
  5. Press delete and click OK when asked to confirm the row delete.

This is where we got to with the original SDK, but the SP1 install will still fail if we leave it like that. As part of SP1 Microsoft has added automatic updates and automatic error reporting. Unfortunately the exe they call as a custom action doesn’t work on x64 (it looks like it puts registry entries in the wrong place), which causes the install to fail. We could extract the MSI, patch the custom exe with corflags and then run setup, but we won’t do that because:

a) We don’t want automatic updates as they will overwrite our nicely patched exes, and
b) x64 is not a supported platform, so I’m sure Microsoft aren’t particularly interested in error reports!

Instead of that we can just continue with Orca to remove those commands from the installer:

  1. From Orca, select “InstallExecuteSequence” in the list on the left and remove SetCreateSqmMachineGuid and CreateSqmMachineGuid as before:Remove Sqm
  2. Click Save on the toolbar

Now you can quit Orca and run the msi, which should install just fine. Make sure you also switch off automatic updates and error reporting as follows:

Surface SDK SP1 Wizard 1 Surface SDK SP1 Wizard 2Surface SDK SP1 Wizard 3

Now the SDK is installed, head over to the original post and follow steps 2 and 3 and you’re all done.

Thanks to JamesK for his workaround comment on the original post.

Update: thanks to Michael Zervos for letting me know that the academic version of the SDK comes in EXE, rather than MSI form. As he points out on his blog, if you keep an eye on your %temp% directory when you run the EXE it will extract the MSI for you to copy and patch.

Update again: Thanks to Robin Sanner for providing details on getting the samples to work:

To get the samples to build and install correctly do the following:

– Edit the configuration properties for the sample solution and create an x86 platform for all projects.
– Edit InstallSamples.bat
– Comment out the lines on either side of the set as follows:

::FOR /F “eol=H tokens=2*” %%A IN (‘REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Surface\v1.0 /v IsLogicalSurfaceUnit’) DO SET LogicalTableValue=%%B
SET InstallingOnTable=false
::IF %LogicalTableValue%==0×1 SET InstallingOnTable=true

– Change the MSBuildParameters to reference the x86 PlatformName as follows:

SET MSBuildParameters=/p:Configuration=Release;PlatformName=x86 /noconsolelogger /fl /fileLoggerParameters:LogFile=%LogFile%;Append /nologo

Surface SDK on Vista x64

Update: There is a new post on this subject regarding the Surface SDK SP1, and it’s also verified working on Win7 x64 too 🙂

If you are lucky enough to have access to a Surface and/or it’s corresponding SDK, you may have tried to install that SDK on a 64bit Vista installation. If you did you will have been greeted by the following delightful error message:

"Your system does not have the correct version of Windows Vista. You must install Microsoft Surface SDK 1.0 on a 32-bit version of Windows Vista Business, Windows Vista Enterprise, or Windows Vista Ultimate with Service Pack 1 (SP1)."

Rather than grab a different machine with a 32bit install, I thought I’d see whether it was possible to get it up and running on x64. Although it turned out to be quite simple to get working, with no registry hackery required, there may be good reasons why this configuration isn’t supported, so use these instructions at your own risk!

To get things up and running you will need the following:

  • Orca – An MSI editor that is part of the Windows SDK. You can grab from the Microsoft download page, or wherever your search engine of choice takes you.
  • Visual Studio 2008 – You might be able to use C# Express, but I haven’t tried it.

There is nothing particularly nasty in these instructions, but it does involve using the command line.

Step 1 – The MSI

Firstly we need to use Orca to tweak the launch conditions of the MSI. Make sure you’ve installed all of the SDK pre-requisites first, then walk through the following:

  1. Install Orca (link above, or just search for it).
  2. Copy the SurfaceSDK.msi to somewhere on your hard disk, and make sure that it’s not Read Only.
  3. Right click on the MSI and choose Edit with Orca. This will trigger a UAC, but it’s software from Microsoft, so you should be ok to trust it 🙂
  4. Select "LaunchCondition" in the left hand list, then select "Install OR NOT VersionNT64" in the right hand list (see below).
    Orca
  5. Press delete and click OK when asked to confirm the row delete.
  6. Click Save on the toolbar.

Now if you launch are freshly edited MSI you should be able to install it just fine – hurrah! If you try and launch the simulator though then it will crash almost immediately – boo!

We will fix that though in Step 2…

Step 2 – The Simulator

The reason for the almost immediate crash is due to the assemblies being built for "Any CPU", while relying on a library than only exists for x86. When the simulator starts up it launches in 64bit mode and, because you can’t mix x86 and x64 assemblies, it tries to load the x64 version of XNA (which doesn’t exist) and promptly falls over in a giggling heap.

If this was an app we had written, we could simply change the configuration in Visual Studio to x86 and everything would be rosy (more on this later). Unfortunately I don’t happen to have the source code for the SDK knocking around, so we have to resort to a utility that comes with Visual Studio called CorFlags to force everything to load in 32Bit mode. The following instructions assume you have everything installed in default locations, but they should be easily adaptable if you don’t:

  1. Go and find the "Visual Studio 2008 Command Prompt" from your start menu (All Programs, Visual Studio 2008, Visual Studio Tools) right click on it and choose "Run as administrator" (accepting the resulting UAC prompt).
  2. Change to "C:\Program Files (x86)\Microsoft SDKs\Surface\v1.0\Tools\Simulator".
  3. Enter "corflags SurfaceSimulator.exe /32bit+ /force" (without the quotes). We need to use /force because the assemblies are strong named signed, and altering them this way will invalidate that signature. This is unfortunately unavoidable, but I haven’t found any problems from doing so. You will receive a CF011 warning informing you of this 🙂
  4. Change to "C:\Program Files (x86)\Microsoft Surface\v1.0".
  5. Use the same corflags syntax from step 3 on the following files, one by one: Attract.exe, AttractConfig.exe, SurfaceInput.exe, SurfaceOutOfOrder.exe, SurfaceShell.exe.
  6. Close the command prompt and launch the simulator!
    ItWorks

Now we’re at this point we need to make sure our Surface applications are set to run in 32Bit mode, or they will just crash when we launch them. This is very simple to do in Visual Studio, and changing this is usually the first step in troubleshooting any weird and wonderful x64 development glitches.

Step 3 – Our Applications

Setting our applications to 32Bit is extremely easy. You may think this is crippling our applications a bit, but all of the Surface units are running Vista 32 so it really doesn’t make a difference (other than making them work on x64!)

  1. Launch Visual Studio 2008, and either open a solution or create a new one.
  2. Enter Configuration Manager (if you drop down the "Any CPU" box, there’s an option in there).
  3. Under "Active solution platform", select
  4. Select x86 as the Type, Copy settings from Any CPU and make sure "Create new project platforms" is selected:
    NewSolutionPlatform
  5. Click OK

The Platform column for each of your projects should now read "x86", and you should be able to launch your Surface applications in the simulator.

Job done! 😀

As I said earlier, there may be good reasons why x64 isn’t a supported platform, so this method falls strictly in the "it works on my machine" camp.