从 .NET 应用调用互操作 API
作为 C# 桌面应用程序开发者,在 .NET 中,你可以利用表示若干互操作函数和 Windows 运行时 (WinRT) COM 互操作界面的 C# 互操作类。 这其中包括表示 IWindowNative、IInitializeWithWindow、GetWindowIdFromWindow 函数等的 C# 类。
该主题列出了可用的 C# 互操作类,并演示如何使用它们。 该主题末尾的背景部分介绍了互操作接口在 .NET 之前版本中的使用方式,以及更改的原因。
配置 .NET 桌面项目以使用 C# 互操作类
下一部分(可用 C# 互操作类)中列出的 C# 互操作类适用于 .NET,方法是作为 Windows 应用 SDK 的一部分,或通过使用特定目标框架名字对象,后面部分会进行介绍。
在 WinUI 3 C# 桌面项目中
在 Visual Studio 中创建新的 WinUI 3 项目时(请参阅创建你的第一个 WinUI 3 项目),项目已配置,你可立即开始使用所有 C# 互操作类。
在其他 C# 桌面项目类型(WPF 或 WinForms)中
对于其他 .NET 桌面项目类型(例如 Windows Presentation Foundation (WPF) 或 Windows 窗体 (WinForms)),你需要先配置项目,然后才能访问 C# 互操作类。 对于下面列出的第一组类,需要引用 Windows 应用 SDK。 对于第二个集,需要配置面向 Windows 10 版本 1809 或更高版本的目标框架名字对象,如下所示:
打开 C# .NET 桌面项目的项目文件。
在
.csproj
文件中,修改 TargetFramework 元素以面向特定的 .NET 和 Windows SDK 版本。 例如,以下元素适用于面向 Windows 10 版本 2004 的 .NET 6 项目。<PropertyGroup> <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework> </PropertyGroup>
有关详细信息(包括其他受支持值的列表),请参阅使用“目标框架名字对象”选项。
可用的 C# 互操作类
注意
以下类需要 .NET 6 SDK 或更高版本。
下面是可用的 C# 互操作类,它们从其基础互操作函数或 WinRT COM 互操作接口映射。 列出的每个类都实现了其基础互操作 API 的函数/方法,并为参数和返回值提供了类型安全的包装器。 例如, Windows.ApplicationModel.DataTransfer.DragDrop.Core.DragDropManagerInterop.GetForWindow 需要 IntPtr 窗口句柄 (HWND)参数并返回 CoreDragDropManager 对象。 下面的所有 C# 互操作类和关联的方法都是静态的。
作为 Windows 应用 SDK 的一部分提供
Microsoft.UI.Win32Interop 类实现下表中的 C# 互操作方法。 有关代码示例,请参阅管理应用窗口。
互操作函数 | C# 互操作方法 |
---|---|
GetDisplayIdFromMonitor | (Microsoft.UI) DisplayId Win32Interop.GetDisplayIdFromMonitor(IntPtr hmonitor) |
GetIconFromIconId | (Microsoft.UI) IntPtr Win32Interop.GetIconFromIconId(IconId iconId) |
GetIconIdFromIcon | (Microsoft.UI) IconId Win32Interop.GetIconIdFromIcon(IntPtr hicon) |
GetMonitorFromDisplayId | (Microsoft.UI) IntPtr Win32Interop.GetMonitorFromDisplayId(DisplayId displayId) |
GetWindowFromWindowId | (Microsoft.UI) IntPtr Win32Interop.GetWindowFromWindowId(WindowId windowId) |
GetWindowIdFromWindow | (Microsoft.UI) WindowId Win32Interop.GetWindowIdFromWindow(IntPtr hwnd) |
通过目标框架名字对象提供
WinRT COM 互操作接口 | C# 互操作类 |
---|---|
IAccountsSettingsPaneInterop | (Windows.UI.ApplicationSettings) AccountsSettingsPaneInterop |
IDisplayInformationStaticsInterop | 随 TFM net6.0-windows10.0.22621.0 和 .NET 6.0.7 引入。(Windows.Graphics.Display) DisplayInformationInterop |
IDragDropManagerInterop | (Windows.ApplicationModel.DataTransfer.DragDrop.Core) DragDropManagerInterop |
IInitializeWithWindow | (WinRT.Interop) InitializeWithWindow |
IInputPaneInterop | (Windows.UI.ViewManagement) InputPaneInterop |
IPlayToManagerInterop | (Windows.Media.PlayTo) PlayToManagerInterop |
IPrintManagerInterop | (Windows.Graphics.Printing) PrintManagerInterop |
IRadialControllerConfigurationInterop | (Windows.UI.Input) RadialControllerConfigurationInterop |
IRadialControllerIndependentInputSourceInterop | (Windows.UI.Input.Core) RadialControllerIndependentInputSourceInterop |
IRadialControllerInterop | (Windows.UI.Input) RadialControllerInterop |
ISpatialInteractionManagerInterop | (Windows.UI.Input.Spatial) SpatialInteractionManagerInterop |
ISystemMediaTransportControlsInterop | (Windows.Media) SystemMediaTransportControlsInterop |
IUIViewSettingsInterop | (Windows.UI.ViewManagement) UIViewSettingsInterop |
IUserConsentVerifierInterop | (Windows.Security.Credentials.UI) UserConsentVerifierInterop |
IWebAuthenticationCoreManagerInterop | (Windows.Security.Authentication.Web.Core) WebAuthenticationCoreManagerInterop |
IWindowNative | 仅限 WinUI 3 (WinRT.Interop) WindowNative 有关 WPF 和 WinForms 的替代方法,请参阅检索窗口句柄 (HWND)。 |
代码示例
此代码示例演示了如何在 WinUI 3 应用程序中使用其中两个 C# 互操作类(请参阅创建你的第一个 WinUI 3 项目)。 示例场景是显示 Windows.Storage.Pickers.FolderPicker。 但在桌面应用中显示选取器之前,需要先使用所有者窗口的句柄 (HWND) 将其初始化。
- 可以使用 IWindowNative WinRT COM 互操作接口获取窗口句柄 (HWND)。 (查看上一部分中的表)该接口由 WinRT.Interop.WindowNative C# 互操作类表示。 此处,
this
对象是对来自主窗口代码隐藏文件的 Microsoft.UI.Xaml.Window 对象的引用。 - 若要使用所有者窗口初始化一段 UI,请使用 IInitializeWithWindow WinRT COM 互操作界面。 该接口由 WinRT.Interop.InitializeWithWindow C# 互操作类表示。
private async void myButton_Click(object sender, RoutedEventArgs e)
{
// Create a folder picker.
var folderPicker = new Windows.Storage.Pickers.FolderPicker();
// 1. Retrieve the window handle (HWND) of the current WinUI 3 window.
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
// 2. Initialize the folder picker with the window handle (HWND).
WinRT.Interop.InitializeWithWindow.Initialize(folderPicker, hWnd);
// Use the folder picker as usual.
folderPicker.FileTypeFilter.Add("*");
var folder = await folderPicker.PickSingleFolderAsync();
}
另请参阅检索窗口句柄 (HWND) 和显示依赖于 CoreWindow 的 WinRT UI 对象。
背景
以前版本的 .NET Framework 和 .NET Core 有 WinRT 的内置知识。 对于这些以前版本,你可以直接以 C# 定义具有 ComImport 特性的互操作接口,并将投影类直接强制转换为该互操作接口。
由于 WinRT 是一种特定于 Windows 的技术,为了支持 .NET 的可移植性和效率目标,我们从 C# 编译器和 .NET 运行时中移出了 WinRT 保护支持,将其移动到 C#/WinRT 工具包(请参阅对 WinRT 的内置支持已从 .NET 移出)。
尽管 ComImport 技术仍适用于基于 IUnknown的互操作接口,但它已不再适用于基于 IInspectable 的接口;这种接口用于与 WinRT 进行互操作。
因此,作为替换,在 .NET 中,可以使用本主题中所述的 C# 互操作类。
故障排除和已知问题
C# 互操作类当前没有已知问题。 若要提供反馈或报告其他问题,请在 WindowsAppSDK GitHub 存储库中添加对现有问题的反馈或提出新问题。