从 .NET 应用调用互操作 API

作为 C# 桌面应用程序开发人员,在 .NET 中,可以使用表示多个互操作性函数和 Windows 运行时 (WinRT) COM 互操作性接口的 C# 互操作类。 其中包括表示 IWindowNativeIInitializeWithWindowGetWindowIdFromWindow 函数等的 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 或更高版本的目标框架名字对象,如下所示:

  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# 互操作类

Note

下面的类需要 .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)
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.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. 若要使用拥有者窗口初始化一段 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 对象

Background

以前版本的 .NET Framework 和 .NET Core 具有 WinRT 的内置知识。 使用这些以前的版本,可以使用ComImport属性直接在 C# 中定义互操作接口,然后直接将投影类转换为该互操作接口。

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

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

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

故障排除和已知问题

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