本文介绍如何配置桌面应用项目以调用Windows 运行时(WinRT)API,这些 API 支持新式Windows功能,例如通知、文件选取器、共享等。
桌面应用中不支持某些 WinRT API。 有关详细信息,请参阅桌面应用中不支持的Windows 运行时 APIs。
配置.NET项目
.NET 6 或更高版本:使用目标框架标识符选项
在项目文件中指定针对特定 Windows OS 版本的目标框架标识符(TFM)。 这会在生成时添加对相应 Windows SDK 目标包的引用。
在Visual Studio中,在 解决方案资源管理器 中右键单击project,然后选择 Edit Project File。
将 TargetFramework 值替换为特定于Windows的 TFM:
目标 TFM Windows 11 版本 24H2 net8.0-windows10.0.26100.0Windows 11版本 22H2 net8.0-windows10.0.22621.0Windows 11(初始版本) net8.0-windows10.0.22000.0Windows 10 版本 2004 net8.0-windows10.0.19041.0Windows 10 版本1903 net8.0-windows10.0.18362.0Windows 10版本 1809 net8.0-windows10.0.17763.0例:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> </PropertyGroup> </Project>保存并关闭项目文件。
支持最低Windows版本
若要允许应用在早于 TFM 目标的Windows版本上运行,请显式设置 TargetPlatformMinVersion:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
</Project>
当面向多个 OS 版本时,请使用 ApiInformation 检查来保护对某些版本上不可用的 API 的调用。 有关详细信息,请参阅版本自适应应用。
.NET 6 及更高版本中不支持 WinRT API
在 .NET 6 及更高版本中,Windows.UI 命名空间中的多个 WinRT API 不受支持。 请使用 Microsoft.UI 命名空间中的等效 API(由 Windows 应用 SDK 提供)而非:
| 不支持 | 请改用 |
|---|---|
Windows.UI.Colors |
Microsoft.UI.Colors |
Windows.UI.ColorHelper |
Microsoft.UI.ColorHelper |
Windows.UI.Text (大多数类型) |
Microsoft.UI.Text |
Windows.UI.Xaml (所有类型) |
Microsoft.UI.Xaml |
.NET Core 3.x 或 .NET Framework:安装 NuGet 包
如果应用面向 .NET Core 3.x 或 .NET Framework,请安装 Microsoft.Windows.SDK.Contracts NuGet 包:
在Visual Studio中,右键单击项目并选择 Manage NuGet 包。
搜索
Microsoft.Windows.SDK.Contracts。选择与最低Windows目标匹配的包版本:
软件包版本 Windows目标 10.0.19041.xxxx Windows 10 版本 2004 10.0.18362.xxxx Windows 10,版本 1903 10.0.17763.xxxx Windows 10版本 1809 10.0.17134.xxxx Windows 10版本 1803 单击“安装”。
多目标同时支持 .NET 6 及早期 .NET 版本
将项目文件配置为使用适用于 .NET 6+ 的 TFM 方法和早期版本的 NuGet 包:
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>netcoreapp3.1;net8.0-windows10.0.19041.0</TargetFrameworks>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'"
Include="Microsoft.Windows.SDK.Contracts"
Version="10.0.19041.0" />
</ItemGroup>
</Project>
配置 C++ (Win32) 项目
使用 C++/WinRT 在 C++ 桌面应用中调用 WinRT API。
- 新项目:安装 C++/WinRT Visual Studio 扩展(VSIX)并使用其中一个包含的项目模板。
- Existing projects:安装 Microsoft.Windows.CppWinRT NuGet 包。
有关详细信息,请参阅 Visual Studio C++/WinRT 的支持。
示例:发送 Toast 通知
配置项目后,可以直接调用 WinRT API。 以下示例从 WPF 或 Win32 应用发送 toast 通知。
注意
Toast 通知需要应用标识。 打包的应用自动具有标识。 有关解压缩的应用,请参阅 从桌面 C# 应用发送本地 Toast 通知 ,了解所需的其他注册步骤。
using System.Security;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
void ShowToast(string title, string content, string image, string logo)
{
string xmlString =
$@"<toast><visual><binding template='ToastGeneric'>" +
$"<text>{SecurityElement.Escape(title)}</text><text>{SecurityElement.Escape(content)}</text>" +
$"<image src='{SecurityElement.Escape(image)}'/>" +
$"<image src='{SecurityElement.Escape(logo)}' placement='appLogoOverride' hint-crop='circle'/>" +
"</binding></visual></toast>";
XmlDocument toastXml = new XmlDocument();
toastXml.LoadXml(xmlString);
ToastNotificationManager.CreateToastNotifier().Show(new ToastNotification(toastXml));
}
#include <sstream>
#include <string>
#include <string_view>
#include <winrt/Windows.Data.Xml.Dom.h>
#include <winrt/Windows.UI.Notifications.h>
using namespace winrt::Windows::UI::Notifications;
using namespace winrt::Windows::Data::Xml::Dom;
std::wstring XmlEscape(std::wstring_view input)
{
std::wstring result;
result.reserve(input.size());
for (wchar_t ch : input) {
switch (ch) {
case L'&': result += L"&"; break;
case L'<': result += L"<"; break;
case L'>': result += L">"; break;
case L'\'': result += L"'"; break;
case L'"': result += L"""; break;
default: result += ch; break;
}
}
return result;
}
void ShowToast(std::wstring title, std::wstring content, std::wstring image, std::wstring logo)
{
std::wostringstream xml;
xml << L"<toast><visual><binding template='ToastGeneric'>"
<< L"<text>" << XmlEscape(title) << L"</text><text>" << XmlEscape(content) << L"</text>"
<< L"<image src='" << XmlEscape(image) << L"'/>"
<< L"<image src='" << XmlEscape(logo) << L"' placement='appLogoOverride' hint-crop='circle'/>"
<< L"</binding></visual></toast>";
XmlDocument toastXml;
toastXml.LoadXml(xml.str().c_str());
ToastNotificationManager::CreateToastNotifier().Show(ToastNotification(toastXml));
}
有关更多通知场景,请参阅 自适应和交互式通知(Toast 通知)。
条件编译
当在 .NET 6 及更早版本中进行多目标编译时,请使用条件编译在单个项目中编写特定版本的代码:
#if NET6_0_OR_GREATER
// Code that uses .NET 6+ APIs or TFM-available WinRT APIs
#else
// Fallback code for .NET Core 3.x / .NET Framework
#endif
相关内容
- 桌面应用中不支持 Windows 运行时 API
- 使用打包扩展将应用与Windows进行集成
- 使桌面应用现代化