diff --git a/dotnet-desktop-guide/includes/migration-shared.md b/dotnet-desktop-guide/includes/migration-shared.md new file mode 100644 index 0000000000..0dbfc0ed81 --- /dev/null +++ b/dotnet-desktop-guide/includes/migration-shared.md @@ -0,0 +1,221 @@ +--- +author: adegeo +ms.author: adegeo +ms.date: 06/24/2026 +ms.update-cycle: 1825-days +ms.topic: include +--- + +## Why upgrade + +.NET Framework is a Windows-only, closed-source runtime that no longer receives feature updates. While it continues to receive security patches for supported versions, it doesn't benefit from the performance work, language improvements, or active investment that .NET does. If you're maintaining a Windows app on .NET Framework, upgrading to .NET gives you access to a faster, more capable platform that's actively developed in the open. + +Staying current on .NET versions matters too. Each .NET release has a defined support window, and apps running on an out-of-support version stop receiving security patches and fixes. Upgrade before end-of-support to stay protected. + +.NET offers meaningful performance improvements across runtime startup, throughput, and memory usage. Desktop apps on .NET also benefit from ongoing feature investment: + +- Newer controls, accessibility improvements, and high-DPI enhancements. +- Better integration with Windows. Some features, such as Dark Mode on Windows 11, are available only on .NET. +- Newer C# and Visual Basic language features and improved tooling. +- A rich ecosystem of NuGet packages that target .NET. + +.NET releases a new major version every year, alternating between long-term support (LTS) and standard-term support (STS) releases: + +- **LTS releases** are supported for three years and are typically the best choice for production apps that prefer stability. +- **STS releases** are supported for 24 months and are useful when you want to adopt new features sooner. + +Plan your upgrade cadence around these dates so your app is always on a supported version. For the current supported versions and end-of-support dates, see [.NET releases, patches, and support](/dotnet/core/releases-and-support). + +## Upgrade paths + +Most upgrades fall into one of two categories. Identify which path applies to your app, then use the guidance and tooling in this article to complete the work. + +- **From .NET Framework to .NET:** The most significant change. + + The project file format, some APIs, and certain technologies are different. Review the prerequisites, assess your dependencies, and plan for API gaps before you start. + + After your app builds and runs on .NET, you can optionally adopt newer patterns, such as `appsettings.json` configuration, dependency injection, or cloud services. Adopting these patterns is separate from the modernization to .NET and isn't required to complete the upgrade. For ideas and guidance, see [Modernize after upgrading to .NET from .NET Framework](/dotnet/core/porting/modernize). + +- **From an older .NET version to a newer one:** A smaller-scope upgrade. + + The main tasks are updating the target framework moniker, reviewing breaking changes for the versions you're crossing, and updating NuGet dependencies. + +### Upgrade from .NET Framework to .NET + +Upgrading from .NET Framework to .NET is the most significant upgrade path and the primary focus of this section. + +> [!IMPORTANT] +> Even though .NET is a cross-platform technology, Windows desktop apps for .NET remain Windows only. + +One change is the project file format. .NET uses the SDK-style project format, which is more concise than the legacy format. You can convert your project file to SDK-style while it still targets .NET Framework, which reduces the scope of change during the actual port and gives you a better baseline to work from. + +Not all .NET Framework APIs are available in .NET. Some APIs exist on the surface but throw `PlatformNotSupportedException` at runtime. The Windows Compatibility Pack (`Microsoft.Windows.Compatibility` NuGet package) fills many of these gaps by providing access to Windows-specific APIs such as the Windows Registry, Windows Event Log, and more. For details, see [Use the Windows Compatibility Pack to port code to .NET](/dotnet/core/porting/windows-compat-pack). + +Some .NET Framework technologies have no equivalent in .NET and require alternative approaches, such as Application Domains, Code Access Security (CAS), and Windows Workflow Foundation. For more information, see the [Unavailable .NET Framework technologies](#unavailable-net-framework-technologies) section. + +Audit your third-party dependencies. Controls and libraries that target only .NET Framework might not work on .NET. Prefer NuGet packages that target .NET Standard 2.0 or .NET directly. For packages that haven't been ported, look for community alternatives or check whether the Windows Compatibility Pack covers the needed APIs. + +### Upgrade between .NET versions + +Moving from one .NET version to another—for example, from .NET 9 to .NET 10—is typically a smaller effort than modernizing from .NET Framework. The core task is updating the `` property in your project file to the new target framework moniker. For example, changing `net9.0-windows` to `net10.0-windows`. + +Before you update the target, review the breaking changes documentation for every version you're crossing. Breaking changes can be behavioral, affect binary or source compatibility, or change design-time behavior. Even minor version gaps can introduce changes that affect your app. Review [Breaking changes in .NET](/dotnet/core/compatibility/breaking-changes) and filter to the version range you're upgrading across. + +After updating the target framework, update your NuGet dependencies. Packages that target older .NET versions might have newer releases that take advantage of the current runtime. Check for updates and prefer packages that target the version you're moving to. Some packages might also have deprecated APIs or changed behavior in newer versions, so review release notes when updating. + +## GitHub Copilot app modernization + +The [GitHub Copilot modernization agent](/dotnet/core/porting/github-copilot-app-modernization/overview) is the recommended tool for upgrading Windows Forms and WPF apps. It's an AI-powered, end-to-end experience built into GitHub Copilot that handles the entire upgrade process. + +The agent follows a three-stage workflow: + +- **Assessment.** Copilot examines your project structure, dependencies, and code patterns. It identifies breaking changes, API compatibility problems, deprecated patterns, and the overall upgrade scope. It then presents strategy decisions, such as upgrade order and compatibility handling, for you to review before proceeding. + +- **Planning.** Copilot converts the assessment and your confirmed choices into a detailed upgrade plan, documenting upgrade strategies, refactoring approaches, dependency paths, and risk mitigations. + +- **Execution.** Copilot breaks the plan into sequential tasks with validation criteria, applies code fixes, and commits changes incrementally. If it encounters a problem it can't resolve automatically, it asks for your help and learns from the correction. + +All upgrade state is stored in `.github/upgrades/` in your repository, so you can pause and resume across sessions or switch between development environments without losing progress. + +The agent supports these upgrade paths: + +- .NET Framework (any version) to .NET 8 or later +- .NET Core 1.x–3.x to .NET 8 or later +- .NET 5-7 to .NET 8 or later +- Migration to Azure services + +It's available in Visual Studio 2026, Visual Studio 2022 17.14.16+, Visual Studio Code, and GitHub CLI. To start an upgrade in Visual Studio, right-click your solution or project in Solution Explorer and select **Modernize**, or open the GitHub Copilot Chat window and type `@Modernize`. In Visual Studio Code, open the GitHub Copilot Chat panel and type `@modernize-dotnet`. + +For setup and usage details, see [What is GitHub Copilot modernization?](/dotnet/core/porting/github-copilot-app-modernization/overview). + +## Unavailable .NET Framework technologies + +Several .NET Framework technologies have no equivalent in .NET and require alternative approaches before your app can run on the new runtime. Identify whether your app depends on any of these technologies early, because they represent the most disruptive category of migration work. For the full reference, see [.NET Framework technologies unavailable on .NET](/dotnet/core/porting/net-framework-tech-unavailable). + +- **Application domains** + + `AppDomain` isn't supported. Use for dynamic assembly loading, and use separate processes or containers for isolation. Some `AppDomain` API members are present but throw at runtime. + +- **Remoting** + + .NET Remoting isn't supported. Use or for local IPC, or gRPC and ASP.NET Core for cross-machine communication. Calls to `BeginInvoke()` and `EndInvoke()` on delegate objects also throw `PlatformNotSupportedException`. + +- **Code Access Security (CAS)** + + CAS isn't supported and is no longer a security boundary. Use OS-level security boundaries such as virtualization, containers, or user accounts instead. + +- **Security transparency** + + Security transparency, which separated sandboxed code from security-critical code, is no longer supported as a security boundary. Like CAS, this feature relied on runtime enforcement that .NET doesn't provide. Use OS-level isolation mechanisms instead. + +- **Windows Workflow Foundation (WF)** + + WF isn't supported in .NET. If your app hosts or uses workflows, consider [CoreWF](https://github.com/UiPath/corewf), an open-source port of the Windows Workflow Foundation runtime that targets .NET. + +- **System.EnterpriseServices (COM+)** + + isn't supported. Apps that use COM+ services such as object pooling, transactions, or role-based security through `System.EnterpriseServices` need to be redesigned to use alternatives. For distributed transactions, consider `System.Transactions`. For service hosting scenarios, consider ASP.NET Core or worker services. + +Be aware that some APIs in these areas are present in .NET but throw at runtime rather than failing at compile time. Test your app on .NET early in the migration to surface these issues before you invest in a full port. + +## Before you start upgrading from .NET Framework + +Before you begin porting your app to .NET, complete a set of preparatory steps while your project still targets .NET Framework. Doing this groundwork first reduces the scope of change during the actual upgrade and gives you a cleaner, validated baseline to start from. For a complete reference, see [Prerequisites to porting code from .NET Framework](/dotnet/core/porting/premigration-needed-changes). + +- **Upgrade your tooling.** + + Ensure you're running a version of Visual Studio that supports the version of .NET you intend to target. Newer SDK versions include improved migration support, better analyzers, and updated project templates. For the relationship between the .NET SDK, MSBuild, and Visual Studio versions, see [Versioning relationship between the .NET SDK, MSBuild, and Visual Studio](/dotnet/core/porting/versioning-sdk-msbuild-vs). + +- **Target .NET Framework 4.7.2 or later.** + + Retarget your project to .NET Framework 4.7.2 or higher before porting. This version provides the broadest API compatibility surface with .NET Standard 2.0, which reduces the number of API gaps you'll encounter during the upgrade. + + In Visual Studio, right-click the project, select **Properties**, and then change the **Target Framework** dropdown to **.NET Framework 4.7.2**. Recompile and fix any issues before proceeding. + +- **Convert to PackageReference format.** + + If your project uses a `packages.config` file to manage NuGet references, migrate to `PackageReference` format. PackageReference is the modern approach and integrates directly into the SDK-style project format you'll adopt in the next step. + + In Visual Studio, right-click `packages.config` in Solution Explorer and select **Migrate packages.config to PackageReference**. Review the migration output and resolve any warnings before continuing. + +- **Convert to SDK-style project format.** + + Switch your project file to the [SDK-style format](/dotnet/core/project-sdk/overview). SDK-style projects are more concise, support multi-targeting, and are required for .NET. This conversion can be done while still targeting .NET Framework, so it's a safe preparatory step. Many conversion tools handle this automatically, or you can convert manually by replacing the project file content with the SDK-style equivalent and re-adding necessary properties. + +- **Update NuGet dependencies.** + + Update all NuGet packages to their latest versions and prefer packages that target .NET Standard 2.0, rather than packages that target .NET Framework only. This reduces the risk of dependency blockers when you change the target framework. Review package release notes for any breaking changes introduced in newer versions. + +All of the previous suggestions ensure that your projects are in a good state before you upgrade to .NET. + +## Windows Compatibility Pack + +One of the most common issues when porting from .NET Framework is missing APIs. .NET Standard deliberately excludes technologies that can't work across all platforms—such as the Windows Registry, WMI, and reflection emit—so those APIs aren't available by default. The `Microsoft.Windows.Compatibility` NuGet package fills that gap. It provides about 20,000 APIs across the following technology areas: + +- Windows Registry +- Windows Event Log +- Windows Management Instrumentation (WMI) +- Windows Performance Counters +- Directory Services +- Windows Access Control Lists (ACL) +- Windows Services +- Windows Cryptography +- Windows Communication Foundation (WCF) +- Ports, ODBC, CodeDom, and more + +The pack sits on top of .NET Standard 2.0 and is especially useful when modernizing incrementally. It lets you get your app building and running on .NET first, then tackle deeper refactoring later, without having to rewrite Windows-specific API usage up front. + +To add it to your project, install the [`Microsoft.Windows.Compatibility`](https://www.nuget.org/packages/Microsoft.Windows.Compatibility) NuGet package: + +```dotnetcli +dotnet add package Microsoft.Windows.Compatibility +``` + +For full details, see [Use the Windows Compatibility Pack to port code to .NET](/dotnet/core/porting/windows-compat-pack). + +## Breaking changes + +Breaking changes are an expected part of any upgrade, whether you're porting from .NET Framework or moving between .NET versions. Reviewing them before you start prevents surprises late in the migration. For the full reference, see [Breaking changes when porting code](/dotnet/core/porting/breaking-changes). + +Breaking changes fall into several categories, and not all of them cause compile-time errors: + +- **Behavioral changes** affect how an API works at runtime. The signature stays the same, but the output, exceptions thrown, or internal behavior changes. These are the hardest to catch because they don't produce build errors. +- **Binary compatibility** changes affect whether existing compiled assemblies continue to work without recompilation. Removing or altering a public API surface breaks binary compatibility. +- **Source compatibility** changes require you to modify source code before it compiles successfully against the newer version. +- **Design-time compatibility** changes affect how projects open and behave in Visual Studio or other design environments. + +When porting from .NET Framework, you're crossing a large version gap, so the list of potential changes is longer. When upgrading between .NET versions—for example, from .NET 6 to .NET 9—the scope is narrower, but every version in between can introduce changes that affect your app. Review breaking changes for each version you skip, not just the target version. + +Breaking changes specific to Windows Forms are documented in [Breaking changes for migration from .NET Framework to .NET](/dotnet/core/compatibility/breaking-changes). Filter the breaking changes reference to the version range you're upgrading across, and review entries that apply to APIs your app uses. + +## Post-upgrade tasks + +After your app builds and runs on .NET, complete a few cleanup tasks to remove artifacts left over from the upgrade. + +**Review NuGet packages.** + +The upgrade process might have updated packages to newer versions. Some of those newer versions remove dependencies that older versions required. After the upgrade, check each updated package and remove any transitive dependencies that are no longer needed. Review the release notes for updated packages to catch behavioral changes that don't cause build errors. + +**Clean up old NuGet artifacts.** + +If your project used a `packages.config` file to manage NuGet references, it's no longer needed after migrating to `PackageReference` format. Delete it from your project. You can also delete the local `packages` folder in your project or solution directory—NuGet now stores packages in a global cache folder at `.nuget\packages` in your user profile. + +**Update `System.Configuration` references.** + +Most .NET Framework apps reference `System.Configuration` directly. After upgrading, your project might still carry that reference. The `System.Configuration` library reads from the _app.config_ file for run-time configuration. In .NET, replace it with the [`System.Configuration.ConfigurationManager`](https://www.nuget.org/packages/System.Configuration.ConfigurationManager) NuGet package, which provides the same API surface without the direct framework assembly reference. + +## Modernize after upgrading + +Once your app runs on .NET, you can adopt modern patterns that aren't available in .NET Framework. These changes aren't required to complete the upgrade, but they improve maintainability and take advantage of active investment in .NET. For a broader set of ideas, see [Modernize after upgrading to .NET from .NET Framework](/dotnet/core/porting/modernize). + +**Migrate from App.config to appsettings.json.** + +.NET Framework uses _App.config_ for run-time settings such as connection strings and logging configuration. .NET apps typically use _appsettings.json_ instead, provided by the `Microsoft.Extensions.Configuration` NuGet package. Many libraries—including logging providers—have dropped _App.config_ support in favor of _appsettings.json_. Migrating aligns your app with the ecosystem and simplifies configuration as you add new dependencies. + +_App.config_ files continue to work in .NET through the `System.Configuration.ConfigurationManager` NuGet package, so you can migrate incrementally. For guidance, see [Configuration in .NET](/dotnet/core/extensions/configuration). + +**Replace the WebBrowser control with WebView2 (WPF).** + +The control is based on Internet Explorer, which is no longer supported. WPF for .NET can use the `WebView2` control based on Microsoft Edge instead. `WebView2` provides a modern, actively maintained browser control with improved performance, security, and web standards support. + +Add the [`Microsoft.Web.WebView2`](https://www.nuget.org/packages/Microsoft.Web.WebView2/) NuGet package to your project. Depending on which version of Windows a user runs, they might need to install the WebView2 runtime separately. For more information, see [Introduction to Microsoft Edge WebView2](/microsoft-edge/webview2/). diff --git a/dotnet-desktop-guide/winforms/migration/how-to-upgrade-winforms.md b/dotnet-desktop-guide/winforms/migration/how-to-upgrade-winforms.md new file mode 100644 index 0000000000..099368c34b --- /dev/null +++ b/dotnet-desktop-guide/winforms/migration/how-to-upgrade-winforms.md @@ -0,0 +1,238 @@ +--- +title: Upgrade a Windows Forms app to .NET with GitHub Copilot modernization +description: Walk through upgrading a Windows Forms app to .NET by using the GitHub Copilot modernization agent in Visual Studio. +author: adegeo +ms.author: adegeo +ms.date: 06/24/2026 +ms.service: dotnet-desktop +ms.update-cycle: 365-days +ms.topic: upgrade-and-migration-article #Don't change. +ai-usage: ai-assisted +#customer intent: As a developer, I want to use GitHub Copilot modernization to upgrade my Windows Forms project to the latest version of .NET. +--- + +# Upgrade a Windows Forms app to .NET with GitHub Copilot modernization + +This article walks through upgrading a Windows Forms desktop app to .NET by using the GitHub Copilot modernization agent. The agent runs in your editor, analyzes the project, and drives a three-stage workflow: assessment, planning, and execution. + +The example uses the [Matching Game sample][winforms-sample], a small .NET Framework Windows Forms app made up of a main project and a class library. + +## Prerequisites + +- Windows operating system. +- Visual Studio 2026. +- [Download and extract the demo app used with this article.][winforms-sample] +- The .NET SDK for the version you're targeting. This article targets .NET 10. +- A Git repository for the solution. The agent commits its progress, so the project must be under source control. +- GitHub Copilot modernization enabled for Visual Studio. For more information, see [Install GitHub Copilot modernization](/dotnet/core/porting/github-copilot-app-modernization/install). + +> [!TIP] +> Be sure to have a backup of your code, such as in source control or a copy, before you start. + +## Open the solution + +The Matching Game projects target .NET Framework 4.5. Visual Studio prompts you to retarget the projects to a supported version of .NET Framework when you open the solution. + +1. Open the **MatchingGame** solution in Visual Studio. +1. Visual Studio displays the **Target Framework Not Installed** dialog. +1. Select **Update the target to .NET Framework 4.8 (Recommended)**, and then select **Continue**. +1. Open the **Git Changes** window and commit the retargeting changes. + +## Important notes for Visual Basic + +The GitHub Copilot modernization agent doesn't fully support Visual Basic .NET projects. The agent includes guardrails specifically designed to ensure C# projects upgrade reliably, and those guardrails interfere with VB project analysis and execution. If your solution contains VB projects, use one of these alternatives instead: + +- **GitHub Copilot (standard agent)**: Use the regular Copilot agent—without the modernization agent—to guide the upgrade interactively. +- **[Upgrade Assistant](/dotnet/core/porting/upgrade-assistant-install)**: A dedicated migration tool with VB support. + +> [!TIP] +> If your solution contains both C# and VB projects, you can still use the modernization agent for the C# projects. Upgrade the VB projects separately using one of the listed alternatives. + +If you use the standard Copilot agent or upgrade manually, follow these steps: + +1. If the project targets an unsupported version of .NET Framework, retarget it to .NET Framework 4.8 first. Visual Studio prompts you to do this when you open the solution, or you can change it in the project properties. +1. Update any outdated NuGet packages to their latest compatible versions. +1. Create a new VB Windows Forms project using a Visual Studio template or `dotnet new winforms -lang vb`. The template produces an SDK-style project file and settings, which have changed from .NET Framework. +1. Copy your `.vb` source files from the old project folder to the new project folder. +1. Copy any non-code files the project depends on, such as `app.config`, `.settings` files, images, icons, and other embedded resources. +1. Open the old project file (or `packages.config`) and note every NuGet package reference. Add those same packages to the new project using the NuGet Package Manager or `dotnet add package `. +1. If the project references other projects in the solution, re-add those references in the new project. +1. Attempt to build the solution. Don't fix errors yet — the build output gives Copilot a concrete list of issues to work from. +1. Commit the current state to source control so you have a clean baseline before Copilot makes changes. +1. Open GitHub Copilot Chat, and ask it to resolve the remaining issues. For example: + + > This Visual Basic Windows Forms project was migrated from .NET Framework 4.8 to .NET 10. The project file and source files are in place, but the solution doesn't compile. Review the build errors and fix API incompatibilities, missing references, and any configuration migration issues. + +1. Review the changes Copilot proposes, then rebuild and test the project. + +## Initiate the upgrade + +The Matching Game solution contains the **MatchingGame** app and the **MatchingGame.Logic** class library. The agent figures out the project graph on its own, so start the upgrade at the solution level. + +1. In **Solution Explorer**, right-click the solution and select **Modernize**. + + The **GitHub Copilot Chat** window opens and starts a conversation with the modernization agent. + +1. Select a model with strong reasoning and coding capabilities. +1. Tell the agent what you want to do. For example: + + > Upgrade everything to .NET 10. + + The agent reports the current state of the codebase and what it plans to do: + + - **Target Framework**: Indicates that the agent upgrades the projects to .NET 10. + - **Flow Mode**: Defaults to **Automatic**. For complex apps, ask the agent to switch to **Guided** mode. + - **Source Control**: Indicates that the agent creates a new working branch. + + The agent writes its work to `.github/upgrades/scenarios/dotnet-version-upgrade/` in your repository. If that folder already exists from a prior attempt, the agent asks whether to continue or start fresh. + +1. Tell the agent `start` to begin the upgrade process. + +## Review the assessment + +In the assessment stage, the agent examines the project structure, dependencies, and code patterns to identify what needs to change. It writes the results to `assessment.md` in `.github/upgrades/scenarios/dotnet-version-upgrade/`. + +When Copilot finishes the assessment, review the conversation output. It generally starts with something similar to the following: + +``` +Assessment Complete + +I've analyzed the solution and created a full assessment — see .github/upgrades/scenarios/dotnet-version-upgrade/assessment.md. + +Solution summary: +• Target: net48 → net10.0 +• Projects: 2 +• MatchingGame.Logic (Class Library) +• MatchingGame (Windows Forms) +• Issues: 883 (673 mandatory, 210 potential) +• Affected Technologies: Windows Forms (666), GDI+ / System.Drawing (208), Legacy Configuration System (2) + +Key concerns: +• Both projects are legacy-format .csproj files — need conversion to SDK-style +• MatchingGame.csproj has API incompatibilities (binary + source) and an incompatible NuGet package +• WinForms remains supported on .NET 10 (Windows-only TFM) +• No reported security vulnerabilities +``` + +### Breakdown of the assessment + +Copilot opens the `.github/upgrades/scenarios/dotnet-version-upgrade/assessment.md` file in the Visual Studio editor. Scroll down to the `MatchingGame\MatchingGame.csproj` section to see a table of issues: + +> | Technology | Issues | Percentage | Migration Path | +> | :--- | :---: | :---: | :--- | +> | Legacy Configuration System | 2 | 0.2% | Legacy XML-based configuration system (app.config/web.config) that has been replaced by a more flexible configuration model in .NET Core. The old system was rigid and XML-based. Migrate to Microsoft.Extensions.Configuration with JSON/environment variables; use System.Configuration.ConfigurationManager NuGet package as interim bridge if needed. | +> | GDI+ / System.Drawing | 208 | 23.7% | System.Drawing APIs for 2D graphics, imaging, and printing that are available via NuGet package System.Drawing.Common. Note: Not recommended for server scenarios due to Windows dependencies; consider cross-platform alternatives like SkiaSharp or ImageSharp for new code. | +> | Windows Forms | 621 | 76.0% | Windows Forms APIs for building Windows desktop applications with traditional Forms-based UI that are available in .NET on Windows. Enable Windows Forms support: Option 1 (Recommended): Target net10.0-windows; Option 2: Add `true`; Option 3 (Legacy): Use Microsoft.NET.Sdk.WindowsDesktop SDK. | + +Most of these issues aren't real problems. Look at the "Migration Path" column for the _GDI+_ row that lists 208 issues. The assessment flags these APIs because they're available in .NET Framework but not in .NET. The column explains the fix: add the `System.Drawing.Common` NuGet package to restore the APIs. + +The _Windows Forms_ row lists 621 API issues for the same reason. Windows Forms APIs aren't available in .NET by default, but you restore them by targeting a Windows-specific framework like `net10.0-windows` and setting `true` in the project file. The **Option 3** suggests an incorrect option. Older versions of .NET required a Windows Forms project to specifically target the `Microsoft.NET.Sdk.WindowsDesktop` SDK, but now it's automatically referenced when `true` is set. + +> [!TIP] +> To learn more about an option, ask Copilot for more information and context. + +## Review the upgrade options + +After the assessment, the agent presents upgrade strategy decisions and saves them to `upgrade-options.md` in `.github/upgrades/scenarios/dotnet-version-upgrade/`. For the Matching Game sample, the agent selects the following options: + +| Aspect | Decision | Reason | +| --- | --- | --- | +| **Upgrade strategy** | Bottom-up. | The agent upgrades **MatchingGame.Logic** first because **MatchingGame** depends on it, then validates each tier before moving on. | +| **Project approach** | In-place. | Both projects migrate together because no other .NET Framework projects consume them. | +| **Unsupported packages** | Resolve inline. | The assessment found only a few incompatible packages, so the agent researches replacements as it works. | +| **Unsupported API handling** | Fix inline. | Most Windows Forms and GDI+ API changes for .NET are mechanical and don't require a separate planning pass. | +| **Windows native APIs** | Windows Compatibility Pack. | The app uses Windows Forms and GDI+ heavily and is inherently Windows-only. | +| **Nullable reference types** | Leave disabled. | The agent treats enabling nullable as a separate effort after migration. | + +The agent also calls out risks that need your attention. For the Matching Game sample, the agent flags the `MetroFramework` packages because they're only available for .NET Framework. The likely outcome is removing `MetroFramework` and falling back to standard Windows Forms controls, which changes the visual style of the app. + +Review the proposed options and tell the agent what you want to change. For example, tell the agent to enable nullable reference types or to pause and discuss `MetroFramework` replacements first. When you're done, reply `confirm` to lock in the selections and move to planning. + +## Review the plan + +In the planning stage, the agent converts the assessment and your confirmed options into a detailed specification. It writes the result to `plan.md` and creates a `scenario-instructions.md` file that stores preferences, decisions, and custom instructions for the upgrade. + +> [!IMPORTANT] +> If **Flow Mode** is **Automatic**, the agent starts executing the plan without time to review. + +The plan covers items such as the upgrade order across projects, the target framework moniker for each project (`net10.0-windows` for Windows Forms projects), package update paths, and risk mitigations for the breaking changes the assessment found. + +To review and customize the plan: + +1. Open `plan.md` in `.github/upgrades/scenarios/dotnet-version-upgrade/`. +1. Review the upgrade strategies and dependency updates. +1. Edit the plan to adjust steps or add context as needed. +1. Tell the agent to move to the execution stage. + +> [!CAUTION] +> The plan depends on project interdependencies. The upgrade doesn't succeed if you modify the plan in a way that prevents the upgrade path from completing. For example, if **MatchingGame** depends on **MatchingGame.Logic** and you remove **MatchingGame.Logic** from the plan, upgrading **MatchingGame** might fail. + +## Run the upgrade + +In the execution stage, the agent breaks the plan into sequential, concrete tasks with validation criteria. The agent writes the task list to `.github/upgrades/scenarios/dotnet-version-upgrade/tasks.md` and tracks overall progress in that file. For each task, the agent creates a folder under `.github/upgrades/scenarios/dotnet-version-upgrade/tasks/` that contains a Markdown file describing the task and a markdown file that reports the task's progress. + +For the Matching Game sample, the task list typically includes upgrading **MatchingGame.Logic** first, then **MatchingGame**, restoring packages, building the solution, and committing the changes. + +To run the upgrade: + +1. Tell the agent to start the upgrade. +1. Monitor progress by reviewing `tasks.md` as the agent updates task statuses. Open the per-task folders under `tasks/` for the task description and a detailed progress report. +1. If the agent encounters a problem it can't resolve, provide the requested help. For example, the agent might ask you to choose between two replacement APIs or confirm whether to keep a deprecated package. +1. Based on your responses, the agent adapts its strategy to the remaining tasks and continues. + +The agent commits changes according to the Git strategy you configured during pre-initialization: per task, per group of tasks, or at the end. + +### Notes for Visual Basic projects + +Visual Basic Windows Forms projects on .NET Framework often use `System.Configuration` settings files and `My` extensions, such as `My.Computer` and `My.User`. The `My` extensions were removed in .NET. The agent flags these patterns during assessment and proposes fixes during execution, but you might need to confirm individual changes during a guided run. + +If the agent migrates the project but it doesn't compile, verify that the project file targets Windows and references Windows Forms. The `` element should look like the following snippet: + +```xml + + + net10.0-windows + true + WinExe + WindowsForms + + + + +``` + +## Verify the upgrade + +When the upgrade finishes, the agent recommends next steps in the chat response. Prompt the agent to generate a comprehensive change report with "Generate a change report." + +Review the final task status in `tasks.md` and confirm that every step is complete. + +To verify the upgrade: + +1. Build the solution and address any compilation errors. +1. Run the app and confirm that forms load and behave as expected. + + The default font in Windows Forms changed between .NET Framework and .NET, so check forms and custom controls for layout differences. + +1. Run any unit tests in the solution and fix failures. +1. Confirm that updated NuGet packages are compatible with your app. +1. Test the app thoroughly to verify the upgrade succeeded. + +> [!TIP] +> If the project won't run and a debugger can't be attached, try restarting Visual Studio. Migrating project files from .NET Framework to .NET might confuse the Windows Forms designer without a restart. + +The **Windows Forms Matching Game Sample** is now upgraded to .NET 10. + +## Post-upgrade experience + +If you ported the app from .NET Framework to .NET, review [Modernize after upgrading to .NET from .NET Framework](/dotnet/core/porting/modernize) for ideas on adopting newer patterns, such as `appsettings.json` configuration, dependency injection, or cloud services. Adopting these patterns is separate from upgrading to .NET and isn't required to complete the upgrade. + +## Related content + +- [Overview of upgrading Windows Forms apps](index.md) +- [Best practices for GitHub Copilot modernization](/dotnet/core/porting/github-copilot-app-modernization/best-practices) +- [Porting from .NET Framework to .NET](/dotnet/core/porting/) +- [Modernize after upgrading to .NET from .NET Framework](/dotnet/core/porting/modernize) +- [Breaking changes when porting code](/dotnet/core/porting/breaking-changes) + +[winforms-sample]: https://github.com/dotnet/samples/tree/main/upgrades/matching-game-netframework/winforms diff --git a/dotnet-desktop-guide/winforms/migration/index.md b/dotnet-desktop-guide/winforms/migration/index.md index e308b4b669..2e398fbce7 100644 --- a/dotnet-desktop-guide/winforms/migration/index.md +++ b/dotnet-desktop-guide/winforms/migration/index.md @@ -1,131 +1,33 @@ --- -title: Upgrade a .NET Framework WinForms app to .NET -description: Learn how to upgrade a .NET Framework (or previous .NET) Windows Forms application to .NET with the .NET Upgrade Assistant and Visual Studio. -ms.date: 04/02/2025 +title: Overview of upgrading Windows Forms apps +description: "Learn about the upgrade paths available for Windows Forms apps, including modernizing from .NET Framework to .NET and upgrading between .NET versions." +author: adegeo +ms.author: adegeo +ms.topic: overview +ms.date: 06/24/2026 ms.service: dotnet-desktop ms.update-cycle: 365-days -ms.topic: upgrade-and-migration-article #Don't change. -#customer intent: As a developer, I want to use the .NET Upgrade Assistant to automatically upgrade my projects to the latest version of .NET. ---- - -# Migrate from Windows Forms .NET Framework to .NET - -This article describes how to upgrade a Windows Forms desktop app to .NET using .NET Upgrade Assistant. Windows Forms remains a Windows-only framework, even though .NET is a cross-platform technology. - -## Prerequisites - -- Windows Operating System. -- [Download and extract the demo app used with this article.][winforms-sample] -- [Visual Studio 2022 version 17.12 or later to target .NET 9.](https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&utm_source=learn.microsoft.com&utm_campaign=inline+link&utm_content=download+vs2022+desktopguide+winforms+migration) -- [.NET Upgrade Assistant extension for Visual Studio.](/dotnet/core/porting/upgrade-assistant-install#install-the-visual-studio-extension) - -## Assessment - -You should analyze your projects before performing an upgrade. Performing code analysis on your projects with .NET Upgrade Assistant generates a report that you can refer to, to identify potential migration blockers. - -To analyze your projects and generate a report, right-click on the solution file in **Solution Explorer** and select **Upgrade**. For more information about performing an analysis, see [Analyze projects with .NET Upgrade Assistant](/dotnet/core/porting/upgrade-assistant-how-to-analyze). - -## Migrate dependencies - -If you're upgrading multiple projects, start with projects that have no dependencies. In the Matching Game sample, the **MatchingGame** project depends on the **MatchingGame.Logic** library, so **MatchingGame.Logic** should be upgraded first. - -> [!TIP] -> Be sure to have a backup of your code, such as in source control or a copy. - -Use the following steps to upgrade a project in Visual Studio: - -01. Right-click on the **MatchingGame.Logic** project in the **Solution Explorer** window and select **Upgrade**: - - :::image type="content" source="media/index/vs-upgrade.png" alt-text="A screenshot of the .NET Upgrade Assistant's Upgrade menu item in Visual Studio."::: - - A new tab is opened that prompts you to choose which upgrade you want to perform. - -01. Select **In-place project upgrade**. - - :::image type="content" source="media/index/step-1-inplace.png" alt-text="A screenshot of the .NET Upgrade Assistant tab. The 'In-place project upgrade' option is highlighted."::: - -01. Next, select the target framework. - - Based on the type of project you're upgrading, you're presented with different options. **.NET Standard 2.0** can be used by both .NET Framework and .NET. This is a good choice if the library doesn't rely on a desktop technology like Windows Forms, which this project does. - - Select **.NET 9.0** and then select **Next**. - - :::image type="content" source="media/index/step-2-framework.png" alt-text="A screenshot of the .NET Upgrade Assistant. The target framework prompt is open and .NET 8 is highlighted along with the 'Next' button."::: - -01. A tree is shown with all of the artifacts related to the project, such as code files and libraries. You can upgrade individual artifacts or the entire project, which is the default. Select **Upgrade selection** to start the upgrade. - - :::image type="content" source="media/index/step-3-components.png" alt-text="A screenshot of the .NET Upgrade Assistant. The 'Select Components' page is open with the 'Upgrade selection' button highlighted."::: +ai-usage: ai-assisted -01. When the upgrade is finished, the results are displayed: +#customer intent: As a developer who maintains an existing Windows Forms app, I want to understand my upgrade options so that I can plan and execute an upgrade to .NET. - :::image type="content" source="media/index/step-4-results1.png" alt-text="A screenshot of the .NET Upgrade Assistant's upgrade results tab, showing the migrated items from the project."::: - - Artifacts with a solid green circle were upgraded while empty green circles were skipped. Skipped artifacts mean that the upgrade assistant didn't find anything to upgrade. - -Now that the app's supporting library is upgraded, upgrade the main app. - -### Notes for Visual Basic projects - -Currently, the .NET Upgrade Assistant doesn't recognize the use of `System.Configuration` in the settings file created by the Visual Basic templates on .NET Framework. It also doesn't respect the use of the `My` extensions used in .NET Framework projects, such as `My.Computer` and `My.User`. These extensions were removed in .NET. Because of these two problems, a Visual Basic library won't compile after being migrated with .NET Upgrade Assistant. - -To fix this problem, the project must target Windows and reference Windows Forms. - -01. After the migration is complete, double-click the **MatchingGame.Logic** project in the **Solution Explorer** window. -01. Locate the `/` element. -01. In the XML editor, change the value of `` from `net9.0` to `net9.0-windows`. -01. Add `true` to the line after ``. - -The project settings should look like the following snippet: - -```xml - - - net9.0-windows - true - Library - Windows - - ... other settings removed for brevity ... -``` - -## Migrate the main project - -Once all of the supporting libraries are upgraded, the main app project can be upgraded. With the example app, there's only one library project to upgrade, which was upgraded in the previous section. - -01. Right-click on the **MatchingGame** project in the **Solution Explorer** window and select **Upgrade**: -01. Select **In-place project upgrade**. -01. Select **.NET 9.0** for the target framework and select **Next**. -01. Leave all of the artifacts selected and select **Upgrade selection**. - -After the upgrade is complete, the results are shown. Notice how the Windows Forms project has a warning symbol. Expand that item and more information is shown about that step: - -:::image type="content" source="media/index/step-4-results2.png" alt-text="A screenshot of the .NET Upgrade Assistant's upgrade results tab, showing some of the result items have warning symbols."::: - -Notice that the project upgrade component mentions that the default font changed. Because the font might affect control layout, you need to check every form and custom control in your project to ensure the UI is arranged correctly. - -## Generate a clean build - -After your main project is upgraded, clean and compile it. +--- -01. Right-click on the **MatchingGame** project in the **Solution Explorer** window and select **Clean**. -01. Right-click on the **MatchingGame** project in the **Solution Explorer** window and select **Build**. +# Overview of upgrading Windows Forms apps -If your application encountered any errors, you can find them in the **Error List** window with a recommendation how to fix them. +This article helps you understand what's involved in upgrading a Windows Forms app from .NET Framework to .NET. Windows Forms is supported on .NET and receives active investment, including newer controls, high-DPI improvements, and accessibility updates. If you maintain an existing Windows Forms app and want to take advantage of those improvements or move to a supported .NET version, this article is for you. -The **Windows Forms Matching Game Sample** project is now upgraded to .NET 9. +The article covers the reasons to upgrade, the available upgrade paths, and the preparation work that makes the upgrade go smoothly. It also explains which .NET Framework technologies have no equivalent in .NET, how to fill API gaps using the Windows Compatibility Pack, and how breaking changes can affect your app. -## Post-upgrade experience +For an example on how to upgrade, see [Upgrade a Windows Forms app to .NET with GitHub Copilot modernization](how-to-upgrade-winforms.md). -If you're porting an app from .NET Framework to .NET, review the [Modernize after upgrading to .NET from .NET Framework](/dotnet/core/porting/modernize) article. +[!INCLUDE [migration-shared](../../includes/migration-shared.md)] ## Related content -- [Porting from .NET Framework to .NET.](/dotnet/core/porting/) - - The porting guide provides an overview of what you should consider when porting your code from .NET Framework to .NET. The complexity of your projects dictates how much work you'll do after the initial migration of the project files. - -- [Modernize after upgrading to .NET from .NET Framework.](/dotnet/core/porting/modernize) - - The world of .NET has changed a lot since .NET Framework. This link provides some information about how to modernize your app after you upgrade. - -[winforms-sample]: https://github.com/dotnet/samples/tree/main/windowsforms/matching-game +- [Upgrade a Windows Forms app to .NET with GitHub Copilot](how-to-upgrade-winforms.md) +- [Port from .NET Framework to .NET](/dotnet/core/porting/framework-overview) +- [.NET Framework technologies unavailable on .NET 6+](/dotnet/core/porting/net-framework-tech-unavailable) +- [Prerequisites to port from .NET Framework](/dotnet/core/porting/premigration-needed-changes) +- [.NET breaking changes reference](/dotnet/core/compatibility/breaking-changes) +- [Use the Windows Compatibility Pack to port code](/dotnet/core/porting/windows-compat-pack) diff --git a/dotnet-desktop-guide/winforms/toc.yml b/dotnet-desktop-guide/winforms/toc.yml index 552ffae6f1..6e2a4eea3b 100644 --- a/dotnet-desktop-guide/winforms/toc.yml +++ b/dotnet-desktop-guide/winforms/toc.yml @@ -27,8 +27,10 @@ items: href: get-started/create-app-visual-studio.md - name: Upgrade items: - - name: How to upgrade to the latest .NET + - name: Overview href: migration/index.md + - name: Upgrade from .NET Framework with GitHub Copilot + href: migration/how-to-upgrade-winforms.md - name: Clipboard and DataObject changes in .NET 10 href: migration/clipboard-dataobject-net10.md - name: Accessibility improvements with .NET diff --git a/dotnet-desktop-guide/wpf/migration/differences-from-net-framework.md b/dotnet-desktop-guide/wpf/migration/differences-from-net-framework.md index b7c65901d0..104e0350b4 100644 --- a/dotnet-desktop-guide/wpf/migration/differences-from-net-framework.md +++ b/dotnet-desktop-guide/wpf/migration/differences-from-net-framework.md @@ -1,5 +1,5 @@ --- -title: Differences between .NET Framework and .NET +title: WPF differences between .NET and .NET Framework description: Describes the differences between the .NET Framework implementation of Windows Presentation Foundation (WPF) and .NET WPF. author: adegeo ms.date: 02/15/2023 @@ -9,7 +9,7 @@ ms.author: adegeo ms.topic: concept-article --- -# Differences with WPF .NET +# WPF differences between .NET and .NET Framework This article describes the differences between Windows Presentation Foundation (WPF) on .NET and .NET Framework. WPF for .NET is an [open-source framework](https://github.com/dotnet/wpf) forked from the original WPF for .NET Framework source code. diff --git a/dotnet-desktop-guide/wpf/migration/how-to-upgrade-wpf.md b/dotnet-desktop-guide/wpf/migration/how-to-upgrade-wpf.md new file mode 100644 index 0000000000..61687c5011 --- /dev/null +++ b/dotnet-desktop-guide/wpf/migration/how-to-upgrade-wpf.md @@ -0,0 +1,227 @@ +--- +title: Upgrade a WPF app to .NET with GitHub Copilot modernization +description: Walk through upgrading a WPF app to .NET by using the GitHub Copilot modernization agent in Visual Studio. +author: adegeo +ms.author: adegeo +ms.date: 06/24/2026 +ms.service: dotnet-desktop +ms.update-cycle: 365-days +ms.topic: upgrade-and-migration-article #Don't change. +ai-usage: ai-assisted +#customer intent: As a developer, I want to use GitHub Copilot modernization to upgrade my WPF project to the latest version of .NET. +--- + +# Upgrade a WPF app to .NET with GitHub Copilot modernization + +This article walks through upgrading a WPF desktop app to .NET by using the GitHub Copilot modernization agent. The agent runs in your editor, analyzes the project, and drives a three-stage workflow: assessment, planning, and execution. + +The example uses the [Matching Game sample][wpf-sample], a small .NET Framework WPF app made up of a main project and a class library. + +## Prerequisites + +- Windows operating system. +- Visual Studio 2026. +- [Download and extract the demo app used with this article.][wpf-sample] +- The .NET SDK for the version you're targeting. This article targets .NET 10. +- A Git repository for the solution. The agent commits its progress, so the project must be under source control. +- GitHub Copilot modernization enabled for Visual Studio. For more information, see [Install GitHub Copilot modernization](/dotnet/core/porting/github-copilot-app-modernization/install). + +> [!TIP] +> Be sure to have a backup of your code, such as in source control or a copy, before you start. + +## Open the solution + +The Matching Game projects target .NET Framework 4.5. Visual Studio prompts you to retarget the projects to a supported version of .NET Framework when you open the solution. + +1. Open the **MatchingGame** solution in Visual Studio. +1. Visual Studio displays the **Target Framework Not Installed** dialog. +1. Select **Update the target to .NET Framework 4.8 (Recommended)**, and then select **Continue**. +1. Open the **Git Changes** window and commit the retargeting changes. + +## Important notes for Visual Basic + +The GitHub Copilot modernization agent doesn't fully support Visual Basic .NET projects. The agent includes guardrails specifically designed to ensure C# projects upgrade reliably, and those guardrails interfere with VB project analysis and execution. If your solution contains VB projects, use one of these alternatives instead: + +- **GitHub Copilot (standard agent)**: Use the regular Copilot agent—without the modernization agent—to guide the upgrade interactively. +- **[Install .NET Upgrade Assistant](/dotnet/core/porting/upgrade-assistant-install)**: A dedicated migration tool with VB support. + +> [!TIP] +> If your solution contains both C# and VB projects, you can still use the modernization agent for the C# projects. Upgrade the VB projects separately using one of the alternatives listed above. + +If you use the standard Copilot agent or upgrade manually, follow these steps: + +1. If the project targets an unsupported version of .NET Framework, retarget it to .NET Framework 4.8 first. Visual Studio prompts you to do this when you open the solution, or you can change it in the project properties. +1. Update any outdated NuGet packages to their latest compatible versions. +1. Create a new VB WPF project using a Visual Studio template or `dotnet new wpf -lang vb`. The template produces an SDK-style project file and settings, which have changed from .NET Framework. +1. Copy your `.vb` source files from the old project folder to the new project folder. +1. Copy any non-code files the project depends on, such as `app.config`, `.settings` files, images, icons, and other embedded resources. +1. Open the old project file (or `packages.config`) and note every NuGet package reference. Add those same packages to the new project using the NuGet Package Manager or `dotnet add package `. +1. If the project references other projects in the solution, re-add those references in the new project. +1. Attempt to build the solution. Don't fix errors yet — the build output gives Copilot a concrete list of issues to work from. +1. Commit the current state to source control so you have a clean baseline before Copilot makes changes. +1. Open GitHub Copilot Chat, and ask it to resolve the remaining issues. For example: + + > This Visual Basic WPF project was migrated from .NET Framework 4.8 to .NET 10. The project file and source files are in place, but the solution doesn't compile. Review the build errors and fix API incompatibilities, missing references, and any configuration migration issues. + +1. Review the changes Copilot proposes, then rebuild and test the project. + +## Initiate the upgrade + +The Matching Game solution contains the **MatchingGame** app and the **MatchingGame.Logic** class library. The agent figures out the project graph on its own, so start the upgrade at the solution level. + +1. In **Solution Explorer**, right-click the solution and select **Modernize**. + + The **GitHub Copilot Chat** window opens and starts a conversation with the modernization agent. + +1. Select a model with strong reasoning and coding capabilities. +1. Tell the agent what you want to do. For example: + + > Upgrade everything to .NET 10. + + The agent reports the current state of the codebase and what it plans to do: + + - **Target Framework**: Indicates that the agent upgrades the projects to .NET 10. + - **Flow Mode**: Defaults to **Automatic**. For complex apps, ask the agent to switch to **Guided** mode. + - **Source Control**: Indicates that the agent creates a new working branch. + + The agent writes its work to `.github/upgrades/scenarios/dotnet-version-upgrade/` in your repository. If that folder already exists from a prior attempt, the agent asks whether to continue or start fresh. + +1. Tell the agent `start` to begin the upgrade process. + +## Review the assessment + +In the assessment stage, the agent examines the project structure, dependencies, and code patterns to identify what needs to change. It writes the results to `assessment.md` in `.github/upgrades/scenarios/dotnet-version-upgrade/`. + +When Copilot finishes the assessment, review the conversation output. It generally starts with something similar to the following: + +``` +Assessment Complete + +I've analyzed the solution and created a full assessment — see .github/upgrades/scenarios/dotnet-version-upgrade/assessment.md. + +Solution: MatchingGame.slnx → target: net10.0 + +Compatibility Statistics: + +- Projects: 2 (both currently on net48, legacy project format) +- Issues: 100 (Mandatory: 91, Potential: 9, Optional: 0) +- Affected Files: 6 +- Affected Technologies: WPF (61 issues), Legacy Configuration System (2 issues) + +Projects: + +| Project | Current TFM | Type | +|----------------------------------------------|-------------|-----------------------| +| MatchingGame.Logic\MatchingGame.Logic.csproj | net48 | Classic Class Library | +| MatchingGame\MatchingGame.csproj | net48 | Classic WPF | + +Key issues found: + +- Both projects use legacy (non-SDK-style) project format → must be converted to SDK-style +- Both project target frameworks need to change to net10.0 +- WPF project (MatchingGame.csproj) has binary/source/behavioral API incompatibilities and Legacy Configuration System usage + +No security vulnerabilities were detected, and no NuGet packages are referenced — this is a self-contained WPF + library solution. +Proceeding to planning now. You can ask me to pause and switch to Guided mode at any time. + +``` + +## Review the upgrade options + +After the assessment, the agent presents upgrade strategy decisions and saves them to `upgrade-options.md` in `.github/upgrades/scenarios/dotnet-version-upgrade/`. For the Matching Game sample, the agent selects the following options: + +| Aspect | Decision | Reason | +| --- | --- | --- | +| **Upgrade strategy** | Bottom-up. | The agent upgrades **MatchingGame.Logic** first because **MatchingGame** depends on it, then validates each tier before moving on.| +| **Project approach** | In-place. | Both projects migrate together because no other .NET Framework projects consume them.| +| **Unsupported API handling** | Fix inline. | Most WPF API changes for .NET are mechanical and don't require a separate planning pass.| +| **Windows native APIs** | Windows Compatibility Pack. | The app uses the registry and is inherently Windows-only.| +| **Nullable reference types** | Leave disabled. | The agent treats enabling nullable as a separate effort after migration.| + +The agent also calls out risks that need your attention. Review the proposed options and tell the agent what you want to change. For example, tell the agent to enable nullable reference types or to change how incompatible packages are handled. When you're done, reply `confirm` to lock in the selections and move to planning. + +## Review the plan + +In the planning stage, the agent converts the assessment and your confirmed options into a detailed specification. It writes the result to `plan.md` and creates a `scenario-instructions.md` file that stores preferences, decisions, and custom instructions for the upgrade. + +> [!IMPORTANT] +> If **Flow Mode** is **Automatic**, the agent starts executing the plan without time to review. + +The plan covers items such as the upgrade order across projects, the target framework moniker for each project (`net10.0-windows` for WPF projects), package update paths, and risk mitigations for the breaking changes the assessment found. + +To review and customize the plan: + +1. Open `plan.md` in `.github/upgrades/scenarios/dotnet-version-upgrade/`. +1. Review the upgrade strategies and dependency updates. +1. Edit the plan to adjust steps or add context as needed. +1. Tell the agent to move to the execution stage. + +> [!CAUTION] +> The plan depends on project interdependencies. The upgrade doesn't succeed if you modify the plan in a way that prevents the upgrade path from completing. For example, if **MatchingGame** depends on **MatchingGame.Logic** and you remove **MatchingGame.Logic** from the plan, upgrading **MatchingGame** might fail. + +## Run the upgrade + +In the execution stage, the agent breaks the plan into sequential, concrete tasks with validation criteria. The agent writes the task list to `.github/upgrades/scenarios/dotnet-version-upgrade/tasks.md` and tracks overall progress in that file. For each task, the agent creates a folder under `.github/upgrades/scenarios/dotnet-version-upgrade/tasks/` that contains a Markdown file describing the task and a markdown file that reports the task's progress. + +For the Matching Game sample, the task list typically includes upgrading **MatchingGame.Logic** first, then **MatchingGame**, restoring packages, building the solution, and committing the changes. + +To run the upgrade: + +1. Tell the agent to start the upgrade. +1. Monitor progress by reviewing `tasks.md` as the agent updates task statuses. Open the per-task folders under `tasks/` for the task description and a detailed progress report. +1. If the agent encounters a problem it can't resolve, provide the requested help. For example, the agent might ask you to choose between two replacement APIs or confirm whether to keep a deprecated package. +1. Based on your responses, the agent adapts its strategy to the remaining tasks and continues. + +The agent commits changes according to the Git strategy you configured during pre-initialization: per task, per group of tasks, or at the end. + +### Notes for Visual Basic projects + +Visual Basic WPF projects on .NET Framework often use `System.Configuration` settings files and `My` extensions, such as `My.Computer` and `My.User`. The `My` extensions were removed in .NET. The agent flags these patterns during assessment and proposes fixes during execution, but you might need to confirm individual changes during a guided run. + +If the agent migrates the project but it doesn't compile, verify that the project file targets Windows and references WPF. The `` element should look like the following snippet: + +```xml + + + net10.0-windows + true + WinExe + Windows + + + + +``` + +## Verify the upgrade + +When the upgrade finishes, the agent recommends next steps in the chat response. Prompt the agent to generate a comprehensive change report with "Generate a change report." + +Review the final task status in `tasks.md` and confirm that every step is complete. + +To verify the upgrade: + +1. Build the solution and address any compilation errors. +1. Run the app and confirm that windows and views load and behave as expected. Review any visual or behavioral differences in XAML controls and custom controls between .NET Framework and .NET. +1. Run any unit tests in the solution and fix failures. +1. Confirm that updated NuGet packages are compatible with your app. +1. Test the app thoroughly to verify the upgrade succeeded. + +> [!TIP] +> If the project won't run and a debugger can't be attached, try restarting Visual Studio. Migrating project files from .NET Framework to .NET might confuse the WPF designer without a restart. + +The **WPF Matching Game Sample** is now upgraded to .NET 10. + +## Post-upgrade experience + +If you ported the app from .NET Framework to .NET, review [Modernize your upgraded .NET Framework apps](/dotnet/core/porting/modernize) for ideas on adopting newer patterns, such as `appsettings.json` configuration, dependency injection, or cloud services. Adopting these patterns is separate from upgrading to .NET and isn't required to complete the upgrade. + +## Related content + +- [Overview of upgrading WPF apps](index.md) +- [Best practices for GitHub Copilot modernization](/dotnet/core/porting/github-copilot-app-modernization/best-practices) +- [Upgrade .NET apps overview](/dotnet/core/porting/) +- [Modernize your upgraded .NET Framework apps](/dotnet/core/porting/modernize) +- [Breaking changes can affect porting your app](/dotnet/core/porting/breaking-changes) + +[wpf-sample]: https://github.com/dotnet/samples/tree/main/upgrades/matching-game-netframework/wpf diff --git a/dotnet-desktop-guide/wpf/migration/index.md b/dotnet-desktop-guide/wpf/migration/index.md index ce5d934a7e..5995a0f22a 100644 --- a/dotnet-desktop-guide/wpf/migration/index.md +++ b/dotnet-desktop-guide/wpf/migration/index.md @@ -1,169 +1,33 @@ --- -title: Upgrade a WPF app to .NET 8 -description: Learn how to upgrade a .NET Framework (or previous .NET) Windows Presentation Foundation (WPF) application to .NET 8. -ms.date: 02/07/2024 +title: Overview of upgrading WPF apps +description: "Learn about the upgrade paths available for WPF apps, including modernizing from .NET Framework to .NET and upgrading between .NET versions." +author: adegeo +ms.author: adegeo +ms.topic: overview +ms.date: 06/24/2026 ms.service: dotnet-desktop ms.update-cycle: 365-days -ms.topic: how-to ---- - -# How to upgrade a WPF desktop app to .NET 8 - -This article describes how to upgrade a Windows Presentation Foundation (WPF) desktop app to .NET 8. Even though WPF runs on .NET, a cross-platform technology, WPF is still a Windows-only framework. The following WPF-related project types can be upgraded with the .NET Upgrade Assistant: - -- WPF project -- Control library -- .NET library - -If you're upgrading from .NET Framework to .NET, consider reviewing the [Differences with WPF .NET](differences-from-net-framework.md) article and the [Porting from .NET Framework to .NET](/dotnet/core/porting/) guide. - -## Prerequisites - -- Windows operating system -- [Visual Studio 2022 version 17.7 or later to target .NET 8](https://visualstudio.microsoft.com/downloads/) -- [Visual Studio 2022 version 17.1 or later to target .NET 7](https://visualstudio.microsoft.com/downloads/) -- [.NET Upgrade Assistant extension for Visual Studio](/dotnet/core/porting/upgrade-assistant-install#install-the-visual-studio-extension) - -## Demo app - -This article was written in the context of upgrading the **Web Favorites Sample** project, which you can download from the [.NET Samples GitHub repository][wpf-sample]. - -## Initiate the upgrade - -If you're upgrading multiple projects, start with projects that have no dependencies. In the Web Favorites sample, the **WebSiteRatings** project depends on the **StarVoteControl** library, so **StarVoteControl** should be upgraded first. - -> [!TIP] -> Be sure to have a backup of your code, such as in source control or a copy. - -Use the following steps to upgrade a project in Visual Studio: - -01. Right-click on the **StarVoteControl** project in the **Solution Explorer** window and select **Upgrade**: - - :::image type="content" source="media/index/vs-upgrade.png" alt-text="The .NET Upgrade Assistant's Upgrade menu item in Visual Studio."::: - - A new tab is opened that prompts you to choose how you want the upgrade to be performed. - -01. Select **In-place project upgrade**. -01. Next, select the target framework. Based on the type of project you're upgrading, different options are presented. **.NET Standard 2.0** is a good choice if the library doesn't rely on a desktop technology like WPF and can be used by both .NET Framework projects and .NET projects. However, the latest .NET releases provide many language and compiler improvements over .NET Standard. - - Select **.NET 8.0** and then select **Next**. - -01. A tree is shown with all of the artifacts related to the project, such as code files and libraries. You can upgrade individual artifacts or the entire project, which is the default. Select **Upgrade selection** to start the upgrade. - - When the upgrade is finished, the results are displayed: - - :::image type="content" source="media/index/vs-upgrade-results.png" alt-text="The .NET Upgrade Assistant's upgrade results tab, showing 7 out of the 21 items were skipped."::: - - Artifacts with a solid green circle were upgraded while empty green circles were skipped. Skipped artifacts mean that the upgrade assistant didn't find anything to upgrade. - -Now that the app's supporting library is upgraded, upgrade the main app. - -### Upgrade the app - -Once all of the supporting libraries are upgraded, the main app project can be upgraded. Perform the following steps: - -01. Right-click on the **WebSiteRatings** project in the **Solution Explorer** window and select **Upgrade**: -01. Select **In-place project upgrade** as the upgrade mode. -01. Select **.NET 8.0** for the target framework and select **Next**. -01. Leave all of the artifacts selected and select **Upgrade selection**. - -After the upgrade is complete, the results are shown. If an item has a warning symbol, it means that there's a note for you to read, which you can do by expanding the item. - -## Generate a clean build - -After your project is upgraded, clean and compile it. - -01. Right-click on the **WebSiteRatings** project in the **Solution Explorer** window and select **Clean**. -01. Right-click on the **WebSiteRatings** project in the **Solution Explorer** window and select **Build**. - -If your application encountered any errors, you can find them in the **Error List** window with a recommendation how to fix them. - -## Post-upgrade steps +ai-usage: ai-assisted -If your project is being upgraded from .NET Framework to .NET, review the information in the [Modernize after upgrading to .NET from .NET Framework](/dotnet/core/porting/modernize) article. +#customer intent: As a developer who maintains an existing WPF app, I want to understand my upgrade options so that I can plan and execute an upgrade to .NET. -After upgrading, you'll want to: - -- Check your NuGet packages. - - The .NET Upgrade Assistant upgraded some packages to new versions. With the sample app provided in this article, the `Microsoft.Data.Sqlite` NuGet package was upgraded from **1.0.0** to **8.0.x**. However, **1.0.0** depends on the `SQLite` NuGet package, but **8.0.x** removes that dependency. The `SQLite` NuGet package is still referenced by the project, although it's no longer required. *Both the `SQLite` and `SQLite.Native` NuGet packages can be removed from the project.* - -- Clean up the old NuGet packages. - - The _packages.config_ file is no longer required and can be deleted from your project, as the NuGet package references are now declared in the project file. Additionally, the local NuGet package cache folder, named _Packages_, is in either the folder or the parent folder of the project. This local cache folder can be deleted. The new NuGet package references use a global cache folder for packages, available in the user's profile directory, named _.nuget\\packages_. - -- Remove the `System.Configuration` library. - - Most .NET Framework apps reference the `System.Configuration` library. After upgrading, it's possible that this library is still directly referenced. - - The `System.Configuration` library uses the _app.config_ file to provide run-time configuration options to your app. For .NET, this library was replaced by the `System.Configuration.ConfigurationManager` NuGet package. Remove reference to the library and add the NuGet package to your project. - -- Check for places to modernize your app. - - APIs and libraries have changed quite a bit since .NET was released. And in most cases, .NET Framework doesn't have access to these improvements. By upgrading to .NET, your now has access to more modern libraries. - - The next sections describe areas you modernize the sample app used by this article. - -## Modernize: Web browser control - -The control referenced by the WPF sample app is based on Internet Explorer, which is out-of-date. WPF for .NET can use the **WebView2** control based on Microsoft Edge. Complete the following steps to upgrade to the new web browser control: - -01. Add the `Microsoft.Web.WebView2` NuGet package. -01. In the _MainWindow.xaml_ file: - - 01. Import the control to the **wpfControls** namespace in the root element: - - :::code language="xaml" source="./snippets/index/csharp/WebSiteRatings/MainWindow.xaml" range="1-13" highlight="10" ::: - - 01. Down where the `` element is declared, remove the `WebBrowser` control and replace it with the `wpfControls:WebView2` control: - - :::code language="xaml" source="./snippets/index/csharp/WebSiteRatings/MainWindow.xaml" range="51-53" ::: - -01. Edit the _MainWindow.xaml.cs_ code behind file. Update the `ListBox_SelectionChanged` method to set the `browser.Source` property to a valid . This code previously passed in the website URL as a string, but the control requires a `Uri`. - - :::code language="csharp" source="./snippets/index/csharp/WebSiteRatings/MainWindow.xaml.cs" range="38-46" highlight="43" ::: - -Depending on which version of Windows a user of your app is running, they may need to install the WebView2 runtime. For more information, see [Get started with WebView2 in WPF apps](/microsoft-edge/webview2/get-started/wpf). - -## Modernize: appsettings.json - -.NET Framework uses the _App.config_ file to load settings for your app, such as connection strings and logging providers. .NET now uses the _appsettings.json_ file for app settings. _App.config_ files are supported in .NET through the `System.Configuration.ConfigurationManager` NuGet package, and support for _appsettings.json_ is provided by the `Microsoft.Extensions.Configuration` NuGet package. - -As other libraries upgrade to .NET, they modernize by supporting _appsettings.json_ instead of _App.config_. For example, logging providers in .NET Framework that have been upgraded for .NET 6+ no longer use _App.config_ for settings. It's good to follow their direction and also move away from using _App.config_ where you can. - -### Use appsettings.json with the WPF sample app - -As an example, after upgrading the WPF sample app, use _appsettings.json_ for the connection string to the local database. - -01. Remove the `System.Configuration.ConfigurationManager` NuGet package. -01. Add the `Microsoft.Extensions.Configuration.Json` NuGet package. -01. Add a file to the project named _appsettings.json_. -01. Set the _appsettings.json_ file to copy to the output directory. - - Set the **copy to output** setting through Visual Studio using the **Properties** window after selecting the file in the **Solution Explorer**. Alternatively you can edit the project directly and add the following `ItemGroup`: - - ```xml - - - PreserveNewest - - - ``` - -01. Migrate the settings in the _App.config_ file to a new _appsettings.json_ file. - - In the WPF sample app, _app.config_ only contained a single connection string. Edit the _appsettings.json_ file to define the connection string: +--- - :::code language="json" source="./snippets/index/csharp/WebSiteRatings/appsettings.json"::: +# Overview of upgrading WPF apps -01. Edit the _App.xaml.cs_ file, instancing a configuration object that loads the _appsettings.json_ file, the added lines are highlighted: +This article helps you understand what's involved in upgrading a Windows Presentation Foundation (WPF) app from .NET Framework to .NET. WPF is supported on .NET and receives active investment, including performance improvements, accessibility updates, and new features. If you maintain an existing WPF app and want to take advantage of those improvements or move to a supported .NET version, this article is for you. - :::code language="csharp" source="./snippets/index/csharp/WebSiteRatings/App.xaml.cs" highlight="2,11,15-17"::: +The article covers the reasons to upgrade, the available upgrade paths, and the preparation work that makes the upgrade go smoothly. It also explains which .NET Framework technologies have no equivalent in .NET, how to fill API gaps using the Windows Compatibility Pack, and how breaking changes can affect your app. -01. In the _.\\Models\\Database.cs_ file, change the `OpenConnection` method to use the new `App.Config` property. This requires importing the `Microsoft.Extensions.Configuration` namespace: +For more information on changes from .NET Framework, see [WPF differences between .NET and .NET Framework](differences-from-net-framework.md) and [.NET Framework technologies unavailable on .NET](/dotnet/core/porting/net-framework-tech-unavailable). - :::code language="csharp" source="./snippets/index/csharp/WebSiteRatings/Models/Database.cs" range="1-12" highlight="3,9-10" ::: +[!INCLUDE [migration-shared](../../includes/migration-shared.md)] - `GetConnectionString` is an extension method provided by the `Microsoft.Extensions.Configuration` namespace. +## Related content -[wpf-sample]: https://github.com/dotnet/samples/tree/main/wpf/WebSiteBrowser/ +- [WPF differences between .NET and .NET Framework](differences-from-net-framework.md) +- [Upgrade a WPF app to .NET with GitHub Copilot modernization](how-to-upgrade-wpf.md) +- [Overview of porting from .NET Framework to .NET](/dotnet/core/porting/framework-overview) +- [.NET Framework technologies unavailable on .NET](/dotnet/core/porting/net-framework-tech-unavailable) +- [Prerequisites to porting code from .NET Framework](/dotnet/core/porting/premigration-needed-changes) +- [Breaking changes when porting code](/dotnet/core/porting/breaking-changes) diff --git a/dotnet-desktop-guide/wpf/toc.yml b/dotnet-desktop-guide/wpf/toc.yml index 613133a167..e4cbe3a667 100644 --- a/dotnet-desktop-guide/wpf/toc.yml +++ b/dotnet-desktop-guide/wpf/toc.yml @@ -26,10 +26,12 @@ items: href: whats-new/net80.md - name: What's new in .NET 7 href: whats-new/net70.md -- name: Migration +- name: Upgrade items: - - name: Upgrade to .NET 8 + - name: Overview href: migration/index.md + - name: Upgrade from .NET Framework with GitHub Copilot + href: migration/how-to-upgrade-wpf.md - name: Differences from .NET Framework href: migration/differences-from-net-framework.md - name: Application development