从 .NET 应用调用互操作 API

作为 C# 桌面应用程序开发人员,在 .NET 中,可以使用表示多个互操作性函数和 Windows 运行时 (WinRT) COM 互操作性接口的 C# 互操作类。 These include C# classes representing IWindowNative, IInitializeWithWindow, the GetWindowIdFromWindow function, and many others.

本主题列出了可用的 C# 互操作类,并演示如何使用这些类。 The Background section at the end of the topic describes how interop interfaces were used in previous versions of .NET, and why the change was made.

配置 .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. In the .csproj file, modify the TargetFramework element to target a specific .NET and Windows SDK version. 例如,以下元素适用于面向 Windows 10 版本 2004 的 .NET 6 项目。

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

有关详细信息(包括其他受支持值的列表),请参阅使用“目标框架名字对象”选项

可用的 C# 互操作类

Note

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

下面是从其基础互操作函数或 WinRT COM 互操作接口映射的可用 C# 互操作类。 列出的每个类实现其基础互操作 API 的函数/方法,并为参数和返回值提供类型安全的包装器。 For example, Windows.ApplicationModel.DataTransfer.DragDrop.Core.DragDropManagerInterop.GetForWindow requires an IntPtr window handle (HWND) parameter, and returns a CoreDragDropManager object. 下面的所有 C# 互操作类和关联的方法都是静态的。

作为 Windows 应用 SDK 的一部分提供

The Microsoft.UI.Win32Interop class implements the C# interop methods in the table below. 有关代码示例,请参阅 管理应用窗口

Interop function 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)

Code example

此代码示例演示如何在 WinUI 3 应用程序中使用两个 C# 互操作类(请参阅 创建第一个 WinUI 3 项目)。 The example scenario is to display a Windows.Storage.Pickers.FolderPicker. 但在桌面应用中显示选取器之前,需要先使用所有者窗口的句柄 (HWND) 将其初始化。

  1. You can obtain a window handle (HWND) by using the IWindowNative WinRT COM interop interface. And (looking in the table in the previous section) that interface is represented by the WinRT.Interop.WindowNative C# interop class. Here, the this object is a reference to a Microsoft.UI.Xaml.Window object from the main window code-behind file.
  2. To initialize a piece of UI with an owner window, you use the IInitializeWithWindow WinRT COM interop interface. And that interface is represented by the WinRT.Interop.InitializeWithWindow C# interop class.
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 的内置知识。 With those previous versions, you could define an interop interface directly in C# with the ComImport attribute, and then directly cast a projected class to that interop interface.

Since WinRT is a Windows-specific technology, to support the portability and efficiency goals of .NET, we lifted the WinRT projection support out of the C# compiler and .NET runtime, and moved it into the C#/WinRT toolkit (see Built-in support for WinRT is removed from .NET).

While the ComImport technique still works for IUnknown-based interop interfaces, it no longer works for the IInspectable-based interfaces that are used for interoperating with WinRT.

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

故障排除和已知问题

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