Scott Hanselman

Converting a 13 year old .NET WPF app called BabySmash to a self-contained .NET 5 app with the .NET Upgrade Assistant

April 08, 2021 Comment on this post [0] Posted in BabySmash | DotNetCore
Sponsored By

13 years ago I wrote a .NET 3.5 WPF application for my then 2 year old baby/toddler. Maybe he was 18 months. He was small. He now wants to drive. continues to be a thing, even today. Recently "Chris The Meme God" had a 20 million view TikTok featuring BabySmash...where he failed to mention the URL. Sigh.

Anyway, the code has been up at for years and other than a few small fixes, really hasn't been touched in 4 or 5 years.

Until Cathy Sullivan from the .NET team used BabySmash as a test application to upgrade to .NET 5 in the year 2021. She used the .NET Upgrade Assistant. She even LIVE STREAMED the upgrade process!


Cathy sent me a PR and we put the resulting .NET 5 BabySmash application in a new dotnet5 branch at I'd encourage you to check it out as it's very easy to build now.

Make sure you get the dotnet5 branch and "dotnet build" from there, not the main branch.

The version that Cathy sent me built great in Visual Studio but had a small issue when building from the command line. Fortunately Alex Elia followed up with a PR of his own that enabled BabySmash to cleanly build from the command line with just the .NET 5 SDK.

He said:

I wasn't readily able to find artifacts for the .NET 5.0 version of BabySmash, so I made a pull request against the repository with a continuous integration pipeline, updated README and adjustments to enable using the .NET CLI for build/run/publish workflows.

It was a project property [that prevented it from building from the command line.] The .NET CLI targets one version of MSBuild whereas Visual Studio/devenv.exe targets another. There was one particular property, GenerateManifests, in the csproj that the .NET CLI version of MSBuild rejected.

The property GenerateManifests being set to true chain triggers down to a call to MSBuild for a task FormatUrl ( which is fairly intuitively named; It formats a URL. The .NET CLI version of MSBuild does not support this task and thus rejects the build.

Interesting note on why it was difficult to find this. WPF projects trigger a build task called MarkupCompilePass1 ( to process the xaml/cs views files into generated .g.cs and baml files. If the build failed due to the GenerateManifests error then that dotnet.exe process would hang and subsequent builds will fail due to a collision on the WPF .g.cs generated files. 

Fantastic! I followed up with this small tweak to the "dotnet publish" command line which allows us to now to make a single babysmash.exe file that includes the whole app and .NET, with NO INSTALL.

dotnet publish --configuration Release --runtime=win10-x64 --output ./publish -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true --self-contained=true -p:DebugType=None

You can get the babysmash.exe from if you'd like, or just install the old one from!

Sponsor: Extend your runway and expand your reach. Oracle for Startups delivers enterprise cloud at a startup price tag with free cloud credits to help you reel in the big fish—confidently. Learn more!

About Scott

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.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.