Fixing System.Core 2.0.5 FileLoadException, Portable Libraries and Windows XP support
My buddy Greg and I are getting ready to launch our little side startup, and I was going through our product backlog. Our app consists of a global cloud service with Signalr, an iPhone app made with Xamarin tools, and a WPF app.
One of the items in our Trello backlog was "Support Windows XP. Gasp!"
I hadn't given this item much thought, but I figure it was worth a few hours look. If it was easy, why not, right?
Our WPF desktop application was written for .NET 4.5, which isn't supported on Windows XP. I want to my app to support as basic and mainstream a .NET 4 installation as possible.
Could I change my app to target .NET 4 directly? I use the new async and await features extensively.
Well, of course, I remembered Microsoft released the Async Targeting Pack (Microsoft.Bcl.Async) through NuGet to do just this. In fact, if I was targeting .NET 3.5 I could use Omer Mor's AsyncBridge for .NET 3.5, so it's good that I have choices.
I changed my project to target .NET 4, rather than 4.5, installed these NuGets, and recompiled. No problem, right?
However, when I run my application on Windows XP it crashes immediately. Fortunately I have instrumented it with Raygun.io so all my crashes to to the cloud for analysis. It gives me this nice summary:
Here's the important part:
FileLoadException: Could not load file or assembly
'System.Core, Version=22.214.171.124, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes'
or one of its dependencies. The given assembly name or codebase was invalid.
(Exception from HRESULT: 0x80131047)
That's weird, I'm using .NET 4 which includes System.Core version 4.0. I can confirm what's in the GAC (Global Assembly Cache) with this command at the command line. Remember, your computer isn't a black box.
C:\>gacutil /l | find /i "system.core"
System.Core, Version=126.96.36.199, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL
System.Core, Version=188.8.131.52, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL
OK, so there isn't even a System.Core version 2.0.5 in the GAC. Turns out that System.Core 2.0.5 is the Portable Libraries version, meant to be used everywhere (that means, Silverlight, etc, everywhere) so they made the version number compatible.
Because we're building our iPhone app with Xamarin tools and we anticipate supporting other platforms, we use a Portable Library to share code. But, it seems that support for Portable Libraries were enabled on .NET 4 vanilla by the KB2468871 update.
I don't want to require any specific patch level or hotfixes. While this .NET 4 framework update was pushed to machines via Windows Update, for now I want to support the most basic install if I can. So if the issue is Portable Libraries (which I still want to use) then I'll want to bring those shared files in another way.
You can LINK source code in Visual Studio when you Add File by clicking the little dropdown and then Add as Link:
Now my Messages.cs file is a link. See the little shortcut overlay in blue?
I removed the project reference to the Portable Library for this WPF application and brought the code in this way. I'm still sharing core, but just not as a binary for this one application.
Recompile and redeploy and magically .NET 4 WPF application with async/await and MahApps.Metro styling starts up and runs wonderfully on this 12 year old OS with just .NET 4 installed.
For our application this means that my market just got opened up a little and now I can sell my product to the millions of pirated and forever unpatched Windows XP machines in the world. Which is a
Sponsor: Big thanks to Aspose for sponsoring the blog feed this week. Aspose.Total for .NET has all the APIs you need to create, manipulate and convert Microsoft Office documents and a host of other file formats in your applications. Curious? Start a free trial today.
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.
Might want to blot it out.
Async Targeting Pack (Microsoft.Bcl.Async) for .Net 4.0 requires KB2468871 to be installed. So you can use Portable Class Libraries as ultimately you need KB2468871.
> but are they used every day by your target audience so you can make money on them?
Sure it depends on your target audience. If you only target tech geeks, you may very well ignore XP and Vista I suppose. Otherwise, passing on 26% of potential income is a brave decision.
> Do you ever made an app with support on all windows versions? XP/Vista/7 and 8?
> Do you have to fix every single problem that can occur on XP
2x yes. Even though the 4.0/4.5 replacement policy of .NET makes stuff even harder for developers, we still need to support it.
XP is slowly becoming less of an issue, but it can't be ignored just yet.
Ian & Aram - I only want to support it if it's easy for me and requires minimal effort. I figured with a few hours work, I could support it, so it's Win-Win.
Comments are closed.
One question - MS have stopped their support for XP so why did you feel the need to support it for a new development?