从 .NET 应用调用互操作 API

作为 C# 桌面应用程序开发人员,在 .NET 中,可以使用表示多个互操作性函数和 Windows 运行时 (WinRT) COM 互操作性接口的 C# 互操作类。 其中包括表示 IWindowNativeIInitializeWithWindowGetWindowIdFromWindow 函数等的 C# 类。

本主题列出了可用的 C# 互操作类,并演示如何使用这些类。 本主题末尾的 Background 部分介绍了如何在早期版本的 .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 或更高版本的 目标框架标识符,如下所示:

  1. 打开 C# .NET 桌面项目的项目文件。

  2. .csproj 文件中,修改 TargetFramework 元素以面向特定的 .NET 和 Windows SDK 版本。 例如,以下元素适用于面向 Windows 10 版本 2004 的 .NET 6 项目。

    <PropertyGroup>
      <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    </PropertyGroup>
    

有关详细信息(包括其他支持值的列表),请参阅 使用目标框架标识符选项

可用的 C# 互操作类

注释

下面的类需要 .NET 6 SDK 或更高版本。

下面是从其基础互操作函数或 WinRT COM 互操作接口映射的可用 C# 互操作类。 列出的每个类实现其基础互操作 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)
获取图标从图标ID 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.ApplicationSettingsAccountsSettingsPaneInterop
IDisplayInformationStaticsInterop 通过 TFM net6.0-windows10.0.22621.0 和 .NET 6.0.7 引入。

Windows.Graphics.DisplayDisplayInformationInterop
IDragDropManagerInterop Windows.ApplicationModel.DataTransfer.DragDrop.CoreDragDropManagerInterop
IInitializeWithWindow WinRT.InteropInitializeWithWindow
IInputPaneInterop Windows.UI.ViewManagementInputPaneInterop
IPlayToManagerInterop Windows.Media.PlayToPlayToManagerInterop
IPrintManagerInterop Windows.Graphics.PrintingPrintManagerInterop
IRadialControllerConfigurationInterop Windows.UI.InputRadialControllerConfigurationInterop
IRadialControllerIndependentInputSourceInterop Windows.UI.Input.CoreRadialControllerIndependentInputSourceInterop
IRadialControllerInterop Windows.UI.InputRadialControllerInterop
ISpatialInteractionManagerInterop Windows.UI.Input.SpatialSpatialInteractionManagerInterop
ISystemMediaTransportControlsInterop Windows.MediaSystemMediaTransportControlsInterop
IUIViewSettingsInterop Windows.UI.ViewManagementUIViewSettingsInterop
IUserConsentVerifierInterop Windows.Security.Credentials.UIUserConsentVerifierInterop
IWebAuthenticationCoreManagerInterop Windows.Security.Authentication.Web.CoreWebAuthenticationCoreManagerInterop
IWindowNative 仅 WinUI 3

WinRT.InteropWindowNative

有关 WPF 和 WinForms 的替代方案,请参考 检索窗口句柄(HWND)

代码示例

此代码示例演示如何在 WinUI 3 应用程序中使用两个 C# 互操作类(请参阅 创建第一个 WinUI 3 项目)。 示例场景是显示 Windows.Storage.Pickers.FolderPicker。 但在桌面应用中显示选取器之前,必须用所有者窗口的句柄(HWND)初始化它。

  1. 可以使用 IWindowNative WinRT COM 互操作接口来获取窗口句柄(HWND)。 并且(在上一部分的表中查看)该接口由 WinRT.Interop.WindowNative C# 互操作类表示。 此处,this 对象是对主窗口代码隐藏文件中 Microsoft.UI.Xaml.Window 对象的引用。
  2. 要使用所有者窗口初始化一个用户界面元素,请使用 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 的内置知识。 在那些早期版本中,可以使用 ComImport 属性直接在 C# 中定义互操作接口,然后将已投影的类直接转换为该互操作接口。

由于 WinRT 是一种特定于 Windows 的技术,为了支持 .NET 的可移植性和效率目标,因此我们已将 WinRT 投影支持从 C# 编译器和 .NET 运行时提升到 C#/WinRT 工具包中(请参阅 WinRT 的内置支持已从 .NET中删除)。

虽然 ComImport 技术仍适用于基于 IUnknown的 互操作接口,但它不再适用于用于与 WinRT 互操作的基于 IInspectable的 接口。

因此,在 .NET 中,您可以使用本主题中所述的 C# 互操作类来替代之前的功能。

故障排除和已知问题

C# 互操作类目前没有已知问题。 若要提供反馈或报告其他问题,请将反馈添加到现有问题,或在 WindowsAppSDK GitHub 存储库上提交新问题