.NET 8 and .NET 9 stopped getting security patches on 10 November 2026. .NET 10 is the current LTS and is supported until November 2028.

Most upgrade guides are about ASP.NET. Desktop apps break in different places: the clipboard, designer resources, third-party controls, installers and Office add-ins. Here is the checklist I use for WinForms and WPF apps, roughly in the order things go wrong.

0. Find out where you actually are

Open each .csproj and look at the target:

  • net8.0-windows or net9.0-windows: affected, keep reading.
  • <TargetFrameworkVersion>v4.x</TargetFrameworkVersion>: this is .NET Framework. It is not affected by this deadline, because .NET Framework 4.8.1 is supported as part of Windows. Moving to .NET 10 is still worth it, but it is a bigger project (see step 8).

Run dotnet --list-runtimes on a typical user machine too. You will often find several runtimes installed that nobody remembers adding.

1. Buy time with a roll-forward, if you need to

A framework-dependent .NET 8 app will not start on the .NET 10 runtime by default. If you can't migrate this month, you can let it run on a newer major version:

<PropertyGroup> <RollForward>Major</RollForward> </PropertyGroup> 

This is a stopgap, not a migration. The app still runs code compiled against .NET 8 APIs, and every behaviour change in steps 3 to 5 can hit you at runtime instead of at compile time. Test it before you ship it.

2. Retarget and pin the SDK

<TargetFramework>net10.0-windows</TargetFramework> <UseWindowsForms>true</UseWindowsForms> <!-- or <UseWPF>true</UseWPF> --> 

Add a global.json so that everyone on the team, and your CI, builds with the same SDK:

{ "sdk": { "version": "10.0.100", "rollForward": "latestFeature" } } 

If you use Directory.Build.props, change the target framework there once instead of in 40 project files.

3. BinaryFormatter is gone

BinaryFormatter was removed in .NET 9. If you skipped .NET 9, this is the change that will hurt the most. Look for:

  • BinaryFormatter used directly to save state, cache objects or deep-clone them
  • custom types stored in .resx files or user settings
  • EnableUnsafeBinaryFormatterSerialization in a project file (on .NET 8 it hid the problem; now it does nothing)

Replace it with System.Text.Json. For data files you have to read again, write a one-time converter before you remove the old code path.

4. Clipboard and drag-and-drop (WinForms)

In .NET 10, Clipboard.GetData and DataObject.GetData are obsolete (warning WFDEV005). Worse, Clipboard.SetData with a custom type now fails silently: nothing lands on the clipboard and no exception is thrown.

// before Clipboard.SetData("MyApp.Order", order); var o = (Order)Clipboard.GetData("MyApp.Order"); // after Clipboard.SetDataAsJson("MyApp.Order", order); if (Clipboard.TryGetData("MyApp.Order", out Order? o)) { /* ... */ } 

Search the whole solution for GetData( and SetData(, including in-app copy and paste between grids. Users notice this one first.

5. Builds that suddenly fail

Two .NET 10 SDK changes break builds that use TreatWarningsAsErrors:

  • New obsoletion warnings (SYSLIB and WFDEV codes). Fix them; suppress one only with a comment that explains why.
  • NuGet now audits transitive packages for projects targeting .NET 10. An old version of some JSON or HTTP library, deep in your dependency graph, now shows up as an error. dotnet package update --vulnerable fixes most of them. If you really need it, <NuGetAuditMode>direct</NuGetAuditMode> restores the old behaviour.

6. Third-party controls and licences

DevExpress, Telerik, Infragistics, Syncfusion and others support new runtimes only in newer releases. Before you start:

  • find the first version of each suite that lists .NET 10 support
  • check that your licence or subscription covers it (this is usually the slowest step, and it isn't technical)
  • read the vendor's breaking-change notes for the versions you skip

Old abandoned controls with no .NET 10 build are the most common reason a "one-day retarget" turns into a project.

7. Office add-ins: check what you actually have

  • VSTO add-ins run on .NET Framework only. They were never on .NET 8, so this deadline doesn't affect them, and you can't move them to .NET 10 as they are. Your options are to stay on .NET Framework or to rewrite as a COM add-in on modern .NET or as an Office web add-in.
  • COM add-ins on .NET 8 (for example built with Excel-DNA or a custom COM shim): retarget them like any other project, then check that your add-in framework version supports the new runtime, and re-test registration with both 32-bit and 64-bit Office.

8. Coming from .NET Framework 4.x?

Then you also need SDK-style project files, packages.config converted to PackageReference, app.config settings reviewed, and WCF clients moved to the System.ServiceModel.* packages. Some APIs simply don't exist anymore (AppDomains, .NET Remoting, parts of System.Web). Do an assessment before you estimate anything.

About tools: Microsoft has deprecated the .NET Upgrade Assistant in favour of GitHub Copilot app modernization, which needs a paid Copilot plan. The old Upgrade Assistant can still be turned on in Visual Studio 2026 (Tools > Options > Projects and Solutions > Modernization). Both handle the mechanical part well. Neither one knows that your grid vendor changed an event signature.

9. Deployment

  • Framework-dependent: user machines need the .NET 10 Desktop Runtime. Update your installer's prerequisite check, or users get a "you must install .NET" dialog on day one.
  • Self-contained: larger install, but no runtime dependency. This is often the easier choice for apps installed on locked-down PCs.
  • ClickOnce and MSIX both work with .NET 10. Bump the version and test an update from the old version, not only a clean install.

10. What to test by hand

Automated tests rarely cover these:

  • high-DPI and mixed-DPI monitors (forms laid out at 100% and opened at 150%)
  • printing and print preview
  • opening every form in the designer (resx problems show up here first)
  • copy and paste, and drag-and-drop, between your app and Excel
  • first start after an update from the old version (settings, caches, files in the user profile)

For a .NET 8 app with modern dependencies, all of this is usually a day or two of work. For a .NET Framework app with old third-party controls, COM interop and an add-in or two, it is a project, and a short assessment before you start saves the most time.

If you'd like a second pair of eyes on your solution, we do fixed-price WinForms and WPF migration assessments at IntellyCode. Questions are welcome in the comments, too.
WinForms and WPF migration to .NET 10: fixed-price assessment by IntellyCode