P3.NET

.NET Core 3 to Support Windows Desktop

Note: Everything in this post is my own opinion on the topic. It in no way represents the opinions of any one else or any company. Everything stated here should be taken as simply one person’s opinion.

A big announcement out of MSBuild was the support for Windows desktop applications (Winforms, WPF) on .NET Core 3. This came as a surprise to many because Microsoft had deemed UWP to be the Windows platform of choice. It seems that Microsoft has changed their mind but if you look at the history of Core this really shouldn’t be much of a surprise.

.NET Core Background

If you don’t know what .NET Core is then read this. .NET Core is basically a rewrite of .NET Framework from the ground up to be cross-platform and open source. Gone is anything related to Windows. It is a completely different codebase. One of the more confusing aspects of Core is that it shares many of the same namespaces and types as the .NET Framework. The goal was to effectively build a new framework that could be swapped out for .NET Framework.

.NET Core is designed to run under any platform and, being open source, allows anyone to contribute. This is a great goal and will help get .NET on other platforms but it’s useful to pure Windows developers is questionable (see later).

Another confusing aspect is .NET Standard. Calling two frameworks Core and Standard aren’t helping matters but .NET Standard is the specification and .NET Core is the implementation. .NET Core is but one of several implementations. The .NET Framework is an implementation of .NET Standard as well. When one says they are .NET Standard compliant what they are talking about is that they can run on any .NET Standard compliant platform which includes .NET Core and .NET Framework. If an application says they run on .NET Core then they are specifically targeting .NET Core which is but one implementation. It is really no different than when a C++ program is compiled for Intel or Arm or MIPS.

Microsoft is betting the .NET ecosystem on .NET Core/Standard and they are putting all their effort into making it succeed. But there are growing pains. Even Microsoft has identified the (many) cases where you should stick with .NET Framework.

When .NET Core first released you could basically build ASP.NET applications on ASP.NET Core. Given the 20 years that .NET has been around that means the console, Windows Forms and WPF apps that you’ve built won’t work. Asking everyone to just switch to web applications is a no go. While web apps have evolved, they simply cannot do some things that native apps can. Web apps would be overkill for simple utilities and require far more infrastructure to support. It was a logical first step though since web development is a top skill most companies want and there are many, many web applications out there. It also fit nicely into the open source culture and CLI-based mindset that runs rampant in .NET Core. Part of what hurt .NET Core initially was the fact that you lost all the standard tooling that .NET was known for. Even now Visual Studio doesn’t fully support the .NET Core tooling. But, again, this fits into the web developer mindset of wanting to break everything up. In a typical (non-.NET) web shop, developers are used to (and expect to be) running several different tools from shell windows for building, debugging and testing their apps. To a .NET/Visual Studio user this is absurd. To hear the web developer this allows for “swapping out” toolsets and being able to more easily control everything. While that may be true it is hard to imagine that in a typical day you’d want to do that.

Project Files

Seeing as how .NET Core was really written by and for web development it is no surprise that the existing toolsets and XML-based toolsets were thrown out. Enter a brand new project file format based upon JSON and a CLI interface. Even NuGet rewrote their package infrastructure to support this new world order.

There were several problems with this approach. The biggest being that Microsoft’s flagship product, Visual Studio, didn’t really work with it. That is easily fixable with an update but the underlying MSBuild system that supports the build process would also need to be updated and that would break the many, many tools that relied on it. Not to mention the fact that the JSON format, while smaller, didn’t really provide any additional benefits over XML.

Fortunately Microsoft finally decided to do away with the new JSON format. It simply didn’t provide any benefits, beyond size, to warrant the amount of retooling needed. They did however adjust the project file format so it requires a lot less infrastructure. Even today you can migrate to the VS 2017 SDK-based project format and take advantage of the smaller size. There are many advantages of the newer format besides the smaller size. It has built in support for generating NuGet packages, if you need that. Versioning information is now stored in the project file, eliminating another source file. The project can add new files without updating the project file because of globbing. The list goes on. So there is no reason not to switch to the new format even for non-.NET Core applications. Unfortunately it is only supported for a limited set of projects right now. Basically class libraries and ASP.NET Core apps work. Everything else either doesn’t or does with some limitations but you can track the list here.

It really is just a matter of time before all the project types are supported and there really isn’t any downside to the new format. The tooling just isn’t ready yet. There is a

Package Management

Another big impact of .NET Core was breaking NuGet. NuGet itself isn’t tied to .NET Core nor did it really need to change but it did anyway. Some of the changes were likely because the maintainers wanted to “fix things” but we are still living with the impact of those changes, broken packages and tooling.

What we have now is two different package formats. The original version handled modifications to project files, adding source and content files and even running install/uninstall scripts. This is needed for some of the more complex packages like Microsoft’s own EntityFramework. But the new format doesn’t support most of that. You can now add references and content files but you have to define your package in such a way that you can do it either way. Again, tooling hasn’t quite caught up.

Many of the changes wre related to switching to package references. I have to admit I really like this change. Getting rid of yet another project metadata file and storing it directly in the project file should have been done the first time around. But as part of that change the NuGet team “required” a new format. I’ve never heard a reasonable justification about why the existing format couldn’t work but that is what the team said. There has been so many packages broken by this change that even Microsoft’s EntityFramework didn’t work with it for quite a while. Older packages simply won’t install properly.

Now, to be fair, there is some rationale behind the changes. Packages that required install/uninstall scripts don’t behave correctly in all situations so it made sense to break some things but, in my opinion, the way it was handled by the NuGet team (at the time at least) didn’t really help matters nor make the community feel like they even mattered. For the most part the package management issues have been resolved. However there are still some project types it doesn’t work with at all including any .NET Framework application type. Again though this should change over time.

The Death of Windows Forms/WPF

A short while after .NET Core released, UWP support was added, or more correctly, UWP added support for running on .NET Core. As a Windows desktop developer you are going to be writing your apps as console, Winforms, WPF or UWP. Since .NET Core only supports UWP you are stuck with few options. Console applications are partially supported in .NET Core 2.0 but better support is coming in .NET Core 3.

UWP is where Microsoft wants everyone developing but it is Windows 10 only. Even more painful is that the features available in it are tightly coupled with the exact update of Windows 10 you are running. Every update to Windows 10 includes additional functionality for UWP but if you are managing many computers or do not upgrade very often then taking advantage of newer UWP features is going to be difficult in commercial applications. There are many people still on Windows 7 where UWP is a no go.

So what about Winforms and WPF? WPF was supposed to kill Winforms. A completely rewritten UI that wasn’t based upon the old Windows APIs, ability to combine stuff however you needed, 3D graphics support, etc. After it came out Microsoft expected everyone to jump on board but the learning curve was high, the features it offered were great for demos but not so much in LOB applications and it was slow. Some of the issues have been resolved over the years but the damage has been done. Most LOB apps running on .NET are still Winforms either because it was easier or there was no reason to migrate it. Note that this is based upon my experience and what I see in the community. I haven’t seen any official numbers from anyone. So Winforms is still limping along with no changes of mention in the last couple of years.

UWP was supposed to take XAML and bring it to a new level making WPF obsolete. At this point most companies either had Winforms apps that were running fine and didn’t need any of the new features or had already migrated to WPF in the last 10 years and weren’t interested in migrating again. Like Winforms to WPF, this would be a total rewrite of the UI. Unlike the web world, Windows developers don’t like rewriting apps every couple of years. But the biggest nail in the coffin is that companies don’t want to be required to run Windows 10. While Microsoft is reporting a huge install base for Windows 10 the questions in the forums and on blog posts about feature sets indicate a lot of folks haven’t switched off of Windows 7.

So what are you to do if you want to continue to run your Winforms, WPF applications on a previous (or current) version of Windows? Stay on .NET Framework, until .NET Core 3 that is.

Winforms/WPF on .NET Core 3

.NET Core 3 will support Winforms/WPF. Or, again, more correctly Winforms and WPF will support .NET Core. .NET Core itself isn’t changing and these apps will not be cross platform. You will simply be able to run them against .NET Core. This, I believe, will be a major changer in the migration game. Once you can run Winforms/WPF apps on .NET Core then there will be very little reason to stick with the older framework.

Go read the comments for the announcement post linked earlier. The comments range from “about time, I’m onboard” to “.NET Core is ruined” to “what about WCF”. It is almost comical to read. Some Microsoft folks were responding early on to comments but they gave up after a while. It became a whipping post by many folks. Let’s break down some of the comments.

Positive Comments

The positive comments tended to indicate this would allow migration to .NET Core. This is exactly what Microsoft wants. They want to migrate everyone over so they can focus all their time on .NET Core. This is really not much different than the migration from VB6 to VB.NET. .NET Framework will be supported for the life of Windows but as its usage goes down it can be phased out. To get everyone to switch to .NET Core Microsoft has to either provide an easy upgrade path for the bulk of applications or simply support them. For Winforms/WPF they are going the supported route. There may be some changes that need to be made before the final 2019 release but the goal is to allow developers to simply recompile for .NET Core. This would be a huge win for Microsoft. I guess they have finally figured out that UWP isn’t getting the attention they hoped for and so they are holding out the philosophical olive branch. This is a great call in my opinion.

Cross Platform Comments

The next set of comments criticize Microsoft for changing .NET Core to Windows-specific. These comments indicate users who don’t understand either how .NET Core works or how the support will come. The support is being added as developer packs. .NET Core already supports this for helping to get UWP applications running on .NET Core. It is funny how none of the commenters even went that route. .NET Core itself will not support Winforms/WPF and therefore it is platform agnostic. Winforms/WPF is being made to support .NET Core. Again, exactly like how UWP and other libraries were migrated.

So, yes, if you target Winforms/WPF then you are not cross-platform. But if cross-platform was your goal you probably wouldn’t be targeting either of these anyway. You’d either be using a platform-agnostic framework like Xamarin or web apps. If you’re doing that then Winforms/WPF support would be irrelevant to you. Why would you care if it was cross platform anyway?

The one, positive, takeaway from these comments was the clear desire to have a cross-platform UI library that could be used. There have been attempts over the years to do this in .NET and other languages and some have been more successful than others. At the end of the day I don’t believe it is the job of .NET Core to support this at all. It doesn’t even make sense. .NET Core is designed to be cross platform which includes devices that don’t have a GUI. If .NET Core has to support cross-platform UIs then any .NET Core device would as well. Exactly how a Rasberry PI would handle a UI is beyond me.

There is a desire for a cross-platform UI. Any such library should support .NET Standard. It is not, however, the job of the .NET Core team (or even Microsoft) to build this. It would be better to have the open source community develop a standard and then Apple, Microsoft and others could then implement the standard into .NET Core or whatever.

UWP Comments

Several posters were trying to side track the conversation to compare UWP to WPF. It is often the case that a commenter has an opinion they want to share and they will attach it to any blog article from Microsoft just to be heard. It really makes me wish Microsoft would moderate them a little bit. The .NET Core team isn’t responsible for either UWP or WPF. These comments should be leveled at those teams. It has nothing to do with Winforms/WPF supporting .NET Core. The only linkage is the fact that it was mentioned this would be possible. But, again, the .NET Core team is responsible for .NET Core. The other teams will be responsible for actually converting their libraries to .NET Core.

Open Source Comments

An interesting set of comments appeared about open sourcing Winforms/WPF. This is reasonable idea given the focus on .NET Core being open source but there could be legal issues. Even if the frameworks were open sourced it is unclear whether that would really matter in the long run. I guess the theory is that if it is open source then developers could add new features and fix broken stuff but it would still require Microsoft to invest time and money into supporting and caring for a framework they’d like to move away from. It would be unrealistic to assume that the community would then take over the management of the libraries and it would likely be the death toll for both frameworks. If you look at some of the libraries Microsoft has open sourced in the past because they didn’t want to support them anymore then you find they have been grossly under supported to the point of death. Think Contracts, Rx, etc.

Of course only time would tell but it seems unlikely that open sourcing these frameworks would in any way help them live on or grow. There is also the issue of reliance on the .NET Framework (which is not open source) and any third-party products they may have licensed. Interestingly enough the source code for .NET has been available since at least 2.0 and even today you can browse the source code for most of it. Being able to build and update it probably isn’t going to add much value.

WCF Comments

Similar to the cross platform UI, there was mention of getting WCF working. Of course that sets off a whole new discussion about whether you should even be using WCF. I used to write a lot of WCF and I can appreciate the fact that there is legacy code that simply cannot be migrated easily or for which web APIs aren’t sufficient. But, again, this post was about Winforms/WPF on .NET Core, not every .NET technology I may have ever used. While a valid comment, not appropriate for here. That is why we have GitHub.

Windows 7 Comments

A good set of comments came up about Windows 7. .NET Core runs on Windows 7+ and Winforms/WPF support even earlier versions, except for .NET Framework 4 requirements. So it is natural to assume that this support would work on Windows 7. But it does seem to set up Microsoft for supporting Windows 7 through 2019 which is an interesting scenario.

Entity Framework 6 Comments

In an interesting aside the announcement mentions that EF6 will be supported as well. This is shocking because we have EF Core. Now you will be able to run either EF or EF Core on .NET Core, at least for Windows. This is both interesting and disturbing. What is the rationale behind it? Everybody I know who switched to EF Core love it but the biggest issue is that it lacks some core features they need. Newer versions are solving that issue but if it doesn’t have something you need then you aren’t going to upgrade. Perhaps by supporting EF directly Microsoft is hoping to allow developers to “lift and shift” their entire app over to .NET Core and then begin the process of migrating to EF Core. A smart move but I wonder how much of this will split the community and if .NET Core apps will stick with EF even if EF Core would do the work.

Final Thoughts

I was really excited about Winforms/WPF running on .NET Core. I think this will potentially get .NET Core into the mainstream. Right now I only see it being used for web applications and for folks who are tech experts wanting to show off the “latest thing”. Getting LOB apps into .NET Core would be a win-win for Microsoft. Getting parity between the frameworks is critical.

I was really disappointed with the comments posted about it though. The industry is filled with large egos and you expect some of the comments to be negative but I have to feel for Microsoft when they post stuff like this and then have to listen to all the complaints about potentially unrelated stuff. It has to be a dream crusher. I wonder how much of this would have been said if it were face to face. Just another example of how people can be malicious online because they are (mostly) anonymous.

Overall I see this as a great move. .NET Core is still cross platform. If you are already on .NET Core then nothing changes for you. If you’re hanging out with Winforms/WPF then this will give you the opportunity to switch over with relative ease. If you are more interested in a cross platform library then Winforms/WPF isn’t going to give you that anyway so you’re already looking elsewhere. The focus, in that case, should be identifying a good cross-platform library and supporting it so that it is popular enough to get supported.