Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Для вызова API Win32 из C# рекомендуется использовать CsWin32 — генератор исходного кода, который создает типобезопасные оболочки P/Invoke на этапе компиляции. CsWin32 работает с проектами C# любого типа — WinUI 3, WPF, WinForms, консольными приложениями или библиотеками классов — и избавляет от необходимости вручную писать объявления DllImport или LibraryImport.
Вы перечисляете имена функций Win32, необходимые в текстовом файле, и CsWin32 создает правильные подписи, структуры, константы и COM-интерфейсы автоматически из метаданных пакета SDK Windows.
Выберите подход к обеспечению взаимодействия
| Approach | Когда использовать | Плюсы | Минусы |
|---|---|---|---|
| CsWin32 (рекомендуется) | Любой вызов Win32 или нативного API из C# | Типобезопасный, созданный на основе официальных метаданных Windows SDK, поддерживает маршалинг и структуры, совместим с AOT с возможностью настройки | Требуется пакет NuGet; Созданный код по умолчанию не отображается |
| LibraryImport (.NET 7+) | Разовые вызовы, для которых точно известна сигнатура | Генерируемый источником, совместимый с AOT, без маршалинга во время выполнения | Вы записываете и обслуживаете каждую подпись вручную |
| DllImport (устаревшая версия) | Существующий код или проекты платформы .NET | Работает везде, множество примеров от сообщества | Маршалинг среды выполнения, сигнатуры, подверженные ошибкам |
| C#/WinRT | API среда выполнения Windows (Windows.* пространства имен) |
Проецируемые типы .NET, естественная работа с C# | Только для API WinRT, не для чистого Win32 |
Note
По умолчанию выходные данные CsWin32 используют маршаллировщик среды выполнения .NET и не обеспечивают автоматическую совместимость с AOT. Включите CsWin32RunAsBuildTask и DisableRuntimeMarshalling для NativeAOT или тримминга — см. руководство по AOT для CsWin32.
Tip
Если нужный вам API находится в пространстве имён Windows.* (например, Windows.Storage или Windows.Media), то это API среда выполнения Windows. Используйте проекцию WinRT вместо P/Invoke. См. Вызов API взаимодействия из приложения .NET.
Необходимые условия
- Visual Studio 2022 (версия 17.4 или более поздней версии) или пакет SDK .NET 8+
- Существующий проект C# (WinUI 3, WPF, WinForms или консоль)
Note
Ориентация на .NET Framework или .NET Standard? Задайте в файле проекта значение <LangVersion>9</LangVersion> (или более позднюю версию) и добавьте пакеты NuGet System.Memory и System.Runtime.CompilerServices.Unsafe.
Шаг 1. Установка пакета NuGet CsWin32
В каталоге проекта выполните следующую команду:
dotnet add package Microsoft.Windows.CsWin32
CsWin32 создает код, использующий указатели и небезопасные контексты. Пакет NuGet автоматически включает AllowUnsafeBlocks. Если проект явно задает <AllowUnsafeBlocks>false</AllowUnsafeBlocks>, удалите эту строку или измените ее trueна, в противном случае созданный код не будет компилироваться.
Шаг 2. Запрос необходимых API
Создайте файл с именемNativeMethods.txt в корневом каталоге проекта (рядом с файлом .csproj ). Добавьте одно имя API на строку. В этом пошаговом руководстве начните с простой функции:
GetTickCount
Сохраните файл. CsWin32 считывает его во время компиляции и создает соответствующую оболочку P/Invoke.
Шаг 3. Вызов созданного API
Созданный код находится в Windows.Win32 пространстве имен под статическим PInvokeклассом. Вызовите его как любой другой статический метод:
using Windows.Win32;
// Get the number of milliseconds since the system started.
uint uptime = PInvoke.GetTickCount();
Console.WriteLine($"System uptime: {uptime} ms");
Создайте свой проект. Если имя функции в NativeMethods.txt допустимо, вызов компилируется и выполняется без дополнительной работы.
Распространенные подводные камни
"Не удается увидеть созданный код"
CsWin32 — это генератор источника. Выходные данные не отображаются как файлы в проекте по умолчанию. Чтобы проверить созданный код, выполните следующие действия.
- В Visual Studio разверните анализаторы > зависимостей > Microsoft.Windows. CsWin32 > Microsoft.Windows. CsWin32.SourceGenerator в Обозреватель решений.
- Либо задайте
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>в файле проекта, чтобы записывать сгенерированные исходные файлы в папкуobj/.
Целевой объект платформы AnyCPU
Созданный код CsWin32 работает с AnyCPU. Вам не нужно изменять целевой объект платформы для большинства вызовов Win32.
Получение HWND в WinUI 3
Для многих API Win32 требуется дескриптор окна. В приложении WinUI 3 получите HWND из вашего Window экземпляра:
using WinRT.Interop;
var hWnd = WindowNative.GetWindowHandle(this);
Затем передайте hWnd (как HWND или nint) в функцию Win32. См. раздел «Получение дескриптора окна (HWND)» для получения дополнительных сведений.
Настройка поведения CsWin32
Создайте файл NativeMethods.json рядом с вашим текстовым файлом, чтобы управлять параметрами генерации, такими как маршалинг широких и узких строк или удобные перегрузки:
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"emitSingleFile": false,
"public": true
}
См. справочник по конфигурации CsWin32, чтобы ознакомиться со всеми параметрами.
Дальнейшие действия
- Выбор подхода взаимодействия — руководство по принятию решений для всех методов взаимодействия Windows
- Пошаговое руководство. Приложение WinUI 3 с взаимодействием Win32 — более глубокий пример настройки строки заголовка с помощью CsWin32
- CsWin32 в GitHub — источник, примеры и средство отслеживания проблем
- Platform Invoke (P/Invoke) — .NET документация по основам P/Invoke
- Вызов API взаимодействия из приложения .NET — для сценариев взаимодействия WinRT на основе COM (передача HWND, средства выбора и т. д.)
Windows developer