|
| 1 | +--- |
| 2 | +title: Use the Windows App SDK in a WinForms app |
| 3 | +description: This topic enables you to use Windows App SDK features (such as App Lifecycle, MRT Core, DWriteCore, and others) in a Windows Forms (WinForms) app. |
| 4 | +ms.topic: article |
| 5 | +ms.date: 05/30/2023 |
| 6 | +keywords: windows win32, windows app development, Windows App SDK, Windows Forms, WinForms |
| 7 | +ms.author: stwhi |
| 8 | +author: stevewhims |
| 9 | +ms.localizationpriority: medium |
| 10 | +--- |
| 11 | + |
| 12 | +# Use the Windows App SDK in a Windows Forms (WinForms) app |
| 13 | + |
| 14 | +The [Windows App SDK](/windows/apps/windows-app-sdk/) is the next evolution in the Windows app development platform. But this topic shows how you can use Windows App SDK APIs (and Windows Runtime APIs) in a [Windows Forms (WinForms)](/dotnet/desktop/winforms/) app! |
| 15 | + |
| 16 | +* In many cases, you'll want to recreate your WinForms app in the form of a [Windows UI Library 3 (WinUI 3)](/windows/apps/winui/winui3/) app. Just one of the advantages of moving to WinUI 3 is to have access to the [Fluent Design System](https://www.microsoft.com/design/fluent/) (also see [Design and code Windows apps](/windows/apps/design/)). And WinUI 3 is part of the Windows App SDK—so, naturally, a WinUI 3 app can use the other Windows App SDK features and APIs, as well. This topic doesn't cover the process of migrating your WinForms app to WinUI 3. |
| 17 | +* But if you find that you're using features of WinForms that aren't yet available in WinUI 3, then you can still use Windows App SDK features (such as App Lifecycle, MRT Core, DWriteCore, and others) in your WinForms app. This topic shows you how. |
| 18 | + |
| 19 | +And in case you don't already have an existing WinForms project—or you want to practice the process—this topic includes steps to create a WinForms project so that you can follow along and configure it to call Windows App SDK APIs. |
| 20 | + |
| 21 | +## Prerequisites |
| 22 | + |
| 23 | +1. [Install tools for the Windows App SDK](set-up-your-development-environment.md#install-visual-studio). |
| 24 | +1. This topic covers both unpackaged and packaged WinForms apps. If your WinForms app is unpackaged (which WinForms apps are by default), then ensure that all dependencies for unpackaged apps are installed (see [Windows App SDK deployment guide for framework-dependent apps packaged with external location or unpackaged](deploy-unpackaged-apps.md#prerequisites)). A quick way to do that is to visit [Latest downloads for the Windows App SDK](/windows/apps/windows-app-sdk/downloads), then download and unzip and run one of the stable release **Runtime downloads**. |
| 25 | + |
| 26 | +> [!IMPORTANT] |
| 27 | +> The version of the **Runtime** that you install needs to match the version of the **Microsoft.WindowsAppSDK** NuGet package that you'll install in a later step. |
| 28 | +
|
| 29 | +For more info about the terms *unpackaged* and *packaged*, see [Advantages and disadvantages of packaging your app](/windows/apps/package-and-deploy/). |
| 30 | + |
| 31 | +## Create a WinForms project if you don't already have one |
| 32 | + |
| 33 | +If you already have a WinForms project, then you can move on to the next section. |
| 34 | + |
| 35 | +1. In Visual Studio, create a new C# **Windows Forms App** project (which is a .NET project). Be careful that you choose the project template with the exact name **Windows Forms App**, and not the **Windows Forms App (.NET Framework)** one. |
| 36 | +2. Give the project a name, and accept any default options. |
| 37 | + |
| 38 | +You now have a project that builds an unpackaged WinForms app. |
| 39 | + |
| 40 | +## Configure your WinForms project for Windows App SDK support |
| 41 | + |
| 42 | +First we'll edit the project file. |
| 43 | + |
| 44 | +1. In **Solution Explorer**, right-click your project, and choose **Edit Project File**. |
| 45 | + |
| 46 | +2. This step enables you to call [Windows Runtime (WinRT) APIs](/uwp/api/) (including [Windows App SDK APIs](/windows/windows-app-sdk/api/winrt/)). Inside the **PropertyGroup** element is the **TargetFramework** element, which is set to a value such as *net6.0*. Append to that target framework value a moniker (specifically, a [Target Framework Moniker](/windows/apps/desktop/modernize/desktop-to-uwp-enhance#net-6-and-later-use-the-target-framework-moniker-option)). For example, use the following if your app targets Windows 10, version 2004: |
| 47 | + |
| 48 | + ```xml |
| 49 | + <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework> |
| 50 | + ``` |
| 51 | + |
| 52 | +3. Also inside the **PropertyGroup** element, add a [RuntimeIdentifiers](/dotnet/core/project-sdk/msbuild-props#runtimeidentifiers) element, like this: |
| 53 | + |
| 54 | + ```xml |
| 55 | + <RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers> |
| 56 | + ``` |
| 57 | + |
| 58 | +4. By default, a WinForms app is unpackaged (meaning that it isn't installed by using MSIX). An unpackaged app must initialize the Windows App SDK runtime before using any other feature of the Windows App SDK. You can do that automatically when your app starts via *auto-initialization*. You just set (also inside the **PropertyGroup** element) the `WindowsPackageType` project property appropriately, like this: |
| 59 | + |
| 60 | + ```xml |
| 61 | + <WindowsPackageType>None</WindowsPackageType> |
| 62 | + ``` |
| 63 | + |
| 64 | + If you have advanced needs (such as custom error handling, or to load a specific version of the Windows App SDK), then instead of *auto-initialization* you can call the bootstrapper API explicitly—for more info, see [Use the Windows App SDK runtime for apps packaged with external location or unpackaged](/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time). |
| 65 | + |
| 66 | +5. Save and close the project file. |
| 67 | + |
| 68 | +Next, we'll install the Windows App SDK NuGet package in the project. |
| 69 | + |
| 70 | +6. In **Solution Explorer**, right-click the **Dependencies** node of your project, and choose **Manage Nuget Packages...**. |
| 71 | +7. In the **NuGet Package Manager** window, select the **Browse** tab, and install the *Latest stable* **Microsoft.WindowsAppSDK** package. |
| 72 | + |
| 73 | +## Use some Windows App SDK features in your WinForms app |
| 74 | + |
| 75 | +This section offers a very simple example of calling Windows App SDK APIs from a WinForms app. It uses the MRT Core feature (see [Manage resources with MRT Core](/windows/apps/windows-app-sdk/mrtcore/mrtcore-overview)). If this example works for your WinForms project (and if you created a new one for this walkthrough, then it will), then you can follow these steps. |
| 76 | + |
| 77 | +1. Open `Form1.cs` (using the **View Designer** command), and drag a **Button** and a **Label** out of the **Toolbox** and onto the designer. |
| 78 | + |
| 79 | +2. Double-click *button1* to generate an event handler. |
| 80 | + |
| 81 | +3. Now we'll add some code that uses the [ResourceManager](/windows/windows-app-sdk/api/winrt/microsoft.windows.applicationmodel.resources.resourcemanager) class in the Windows App SDK to load a string resource. |
| 82 | + |
| 83 | + 1. Add a new **Resources File (.resw)** item to your project (leave it with the default name of *Resources.resw*). |
| 84 | + |
| 85 | + 2. With the resources file open in the editor, create a new string resource with the following properties. |
| 86 | + - Name: **Message** |
| 87 | + - Value: **Hello, resources!** |
| 88 | + |
| 89 | + 3. Save and close the resources file. |
| 90 | + |
| 91 | + 4. Open `Form1.cs` (using the **View Code** command), and edit the event handler to look like this: |
| 92 | + |
| 93 | + ```csharp |
| 94 | + private void button1_Click(object sender, EventArgs e) |
| 95 | + { |
| 96 | + // Construct a resource manager using the resource index generated during build. |
| 97 | + var manager = |
| 98 | + new Microsoft.Windows.ApplicationModel.Resources.ResourceManager(); |
| 99 | + |
| 100 | + // Look up a string in the resources file using the string's name. |
| 101 | + label1.Text = manager.MainResourceMap.GetValue("Resources/Message").ValueAsString; |
| 102 | + } |
| 103 | + ``` |
| 104 | + |
| 105 | +4. Build the project, and run the app. Click the button to see the string `Hello, resources!` displayed. |
| 106 | + |
| 107 | +> [!TIP] |
| 108 | +> If at runtime you see a message box indicating that the application needs a particular version of the Windows App Runtime, and asks whether you want to install it now, then click **Yes**. That will take you to [Latest downloads for the Windows App SDK](/windows/apps/windows-app-sdk/downloads). For more info, see the [Prerequisites](#prerequisites) section above. |
| 109 | + |
| 110 | +Also see [Runtime architecture](deployment-architecture.md) to learn more about the *Framework* package dependency that your app takes when it uses the Windows App SDK, and the additional components required to work in an unpackaged app. |
| 111 | + |
| 112 | +## Package and deploy your WinForms app with MSIX |
| 113 | + |
| 114 | +Some Windows features and APIs (including the Windows App SDK [notifications APIs](/windows/windows-app-sdk/api/winrt/microsoft.windows.appnotifications.appnotificationmanager)) require your app to have *package identity* at runtime (in other words, your app needs to be *packaged*). For more info, see [Features that require package identity](/windows/apps/desktop/modernize/modernize-packaged-apps). |
| 115 | + |
| 116 | +1. In **Solution Explorer** in Visual Studio, right-click the solution, and choose **Add** > **New Project...**. |
| 117 | +1. In the **Add a new project** dialog box, search for *packaging*, choose the C# **Windows Application Packaging Project** project template, and click **Next**. |
| 118 | +1. Name the project, and click **Create**. |
| 119 | +1. We want to specify which applications in the solution are to be included in the package. So in the packaging project (*not* the WinForms project), right-click the **Dependencies** node, and choose **Add Project Reference...**. |
| 120 | +1. In the list of projects in the solution, choose your WinForms project, and click **OK**. |
| 121 | +1. Expand the packaging project's **Dependencies** > **Applications** node, and confirm that your WinForms project is referenced and highlighted in bold. This means that it will be used as a starting point for the package. |
| 122 | +1. Right-click the packaging project, and choose **Set As Startup Project**. |
| 123 | +1. Right-click the WinForms project, and choose **Edit Project File**. |
| 124 | +1. Delete `<WindowsPackageType>None</WindowsPackageType>`, save, and close. |
| 125 | +1. In the **Solution Platforms** drop-down, pick *x64* (instead of *Any Cpu*). |
| 126 | +1. Confirm that you can build and run. |
| 127 | + |
| 128 | +Now that you've packaged your WinForms app, you can call APIs that require package identity. So open `Form1.cs` (using the **View Code** command), and edit the event handler to look like this: |
| 129 | + |
| 130 | +```csharp |
| 131 | +private void button1_Click(object sender, EventArgs e) |
| 132 | +{ |
| 133 | + var notification = new AppNotificationBuilder() |
| 134 | + .AddArgument("action", "viewConversation") |
| 135 | + .AddArgument("conversationId", "9813") |
| 136 | + .AddText("Andrew sent you a picture") |
| 137 | + .AddText("Check this out, The Enchantments in Washington!") |
| 138 | + .BuildNotification(); |
| 139 | + |
| 140 | + AppNotificationManager.Default.Show(notification); |
| 141 | +} |
| 142 | +``` |
| 143 | + |
| 144 | +Build and run again. Click the button, and confirm that a toast notification is displayed. When called from a process that lacks package identity at runtime, the notifications APIs throw an exception. |
| 145 | + |
| 146 | +> [!NOTE] |
| 147 | +> The steps in this section showed you how to create a *packaged app*. An alternative is to create a *packaged app with external location*. For a reminder of all these terms, see [Advantages and disadvantages of packaging your app](/windows/apps/package-and-deploy/). |
| 148 | +
|
| 149 | +## Related topics |
| 150 | + |
| 151 | +* [Windows Forms (WinForms)](/dotnet/desktop/winforms/) |
| 152 | +* [Install tools for the Windows App SDK](set-up-your-development-environment.md#install-visual-studio) |
| 153 | +* [Windows App SDK deployment guide for framework-dependent apps packaged with external location or unpackaged](deploy-unpackaged-apps.md#prerequisites) |
| 154 | +* [Latest downloads for the Windows App SDK](/windows/apps/windows-app-sdk/downloads) |
| 155 | +* [Advantages and disadvantages of packaging your app](/windows/apps/package-and-deploy/) |
| 156 | +* [Use the Windows App SDK runtime for apps packaged with external location or unpackaged](/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time) |
| 157 | +* [Runtime architecture](deployment-architecture.md) |
| 158 | +* [Features that require package identity](/windows/apps/desktop/modernize/modernize-packaged-apps) |
0 commit comments