Вызов API взаимодействия из приложения .NET

Как разработчик настольных приложений C#, в .NET вы можете использовать классы взаимодействия C#, которые представляют несколько функций взаимодействия и интерфейсы COM-взаимодействия среды выполнения Windows (WinRT). К ним относятся классы C#, представляющие IWindowNative, IInitializeWithWindow, функцию GetWindowIdFromWindow и многое другое.

В этом разделе перечислены доступные классы взаимодействия C# и показано, как их использовать. В разделе Справочная информация в конце раздела описано, как интерфейсы взаимодействия использовались в предыдущих версиях .NET и почему были внесены изменения.

Настройка проекта классического приложения .NET для использования классов взаимодействия C#

Классы взаимодействия C#, перечисленные в следующем разделе (Доступные классы взаимодействия C#), доступны в .NET как часть пакета SDK для приложений для Windows или с помощью определенного моникера целевой платформы, как мы увидим далее.

Проект классического приложения WinUI 3 на C#

Когда вы создаете новый проект WinUI 3 в Visual Studio (см. статью Создание простого проекта WinUI 3), он уже полностью настроен и вы можете сразу начать использовать все классы взаимодействия C#.

Другие типы проектов классических приложений C# (WPF или WinForms)

Для других типов классических приложений .NET, например Windows Presentation Foundation (WPF) или Windows Forms (WinForms), необходимо настроить проект, прежде чем можно будет получить доступ к классам взаимодействия C#. Для первого набора классов, перечисленных ниже, вам потребуется ссылка на пакет SDK для приложений для Windows. Для второго набора вам нужно настроить моникер целевой платформы, предназначенный для Windows 10 версии 1809 или более поздней, например:

  1. Откройте файл проекта для проекта классического приложения .NET на C#.

  2. В файле .csproj измените элемент TargetFramework, чтобы указать конкретную версию .NET и Windows SDK. Например, следующий элемент подходит для проекта .NET 6, предназначенного для Windows 10 версии 2004.

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

Дополнительные сведения, включая список других поддерживаемых значений, см. в разделе Использование моникера целевой платформы.

Доступные классы взаимодействия C#

Примечание.

В приведенных ниже классах требуется пакет SDK для .NET 6 или более поздних версий.

Ниже перечислены доступные классы взаимодействия C#, сопоставленные с их базовой функцией взаимодействия или интерфейсом COM-взаимодействия WinRT. Каждый перечисленный класс реализует функции или методы лежащего в основе его API взаимодействия и предоставляет типобезопасные оболочки для параметров и возвращаемых значений. Например, Windows.ApplicationModel.DataTransfer.DragDrop.Core.DragDropManagerInterop.GetForWindow требует параметр дескриптора окна IntPtr (HWND) и возвращает объект CoreDragDropManager. Все приведенные ниже классы COM-взаимодействия C# и связанные методы являются статическими.

Доступно как часть пакета SDK для приложений для Windows

Класс 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)

Доступно через моникер целевой платформы

Интерфейс COM-взаимодействия WinRT Класс взаимодействия 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).

Пример кода

В этом примере кода показано, как использовать два из классов взаимодействия C# в приложении WinUI 3 (см. статью Создание простого проекта WinUI 3). В примере сценария показано, как отобразить Windows.Storage.Pickers.FolderPicker. Но перед отображением средства выбора в классическом приложении необходимо инициализировать его с помощью дескриптора (HWND) окна-владельца.

  1. Вы можете получить дескриптор окна (HWND) с помощью интерфейса COM-взаимодействия IWindowNative WinRT. И (см. таблицу в предыдущем разделе) этот интерфейс представлен классом взаимодействия C# WinRT.Interop.WindowNative. Здесь объект this является ссылкой на объект Microsoft.UI.Xaml.Window из файла кода программной части главного окна.
  2. Чтобы инициализировать часть пользовательского интерфейса с окном-владельцем, вы используете интерфейс COM-взаимодействия IIInitializeWithWindow WinRT. И этот интерфейс представлен классом взаимодействия C# WinRT.Interop.InitializeWithWindow.
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) и Отображение объектов пользовательского интерфейса WinRT, зависящих от CoreWindow.

Общие сведения

Предыдущие версии .NET Framework и .NET Core имели встроенную поддержку WinRT. В этих предыдущих версиях вы могли определить интерфейс взаимодействия непосредственно на C# с помощью атрибута ComImport, а затем напрямую привести спроецированный класс к этому интерфейсу взаимодействия.

Так как WinRT — это технология, специфичная для Windows, для обеспечения переносимости и эффективности .NET мы отключили поддержку проекций WinRT в компиляторе C# и среды выполнения .NET и включили ее в наборе инструментов C#/WinRT (см. статью Встроенная поддержка WinRT отключена в .NET).

Хотя метод ComImport по-прежнему работает для интерфейсов взаимодействия на основе IUnknown, он больше не работает для интерфейсов на основе IInspectable, которые используются для взаимодействия с WinRT.

Поэтому в качестве замены в .NET вы можете использовать классы взаимодействия C#, описанные в этом разделе.

Устранение неполадок и известные проблемы

Сейчас нет известных проблем для классов взаимодействия C#. Чтобы оставить отзыв или сообщить о других проблемах, добавьте свой отзыв к существующей проблеме или зарегистрируйте новую проблему в репозитории WindowsAppSDK в GitHub.