Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Zalecanym sposobem wywoływania interfejsów API Win32 z języka C# jest CsWin32 — generator kodu źródłowego, który podczas kompilacji tworzy bezpieczne typowo opakowania P/Invoke. CsWin32 współpracuje z dowolnym typem projektu języka C# — WinUI 3, WPF, WinForms, konsolą lub biblioteką klas — i eliminuje konieczność ręcznego zapisu DllImport lub LibraryImport deklaracji.
Nazwy potrzebnych funkcji Win32 wpisujesz do pliku tekstowego, a CsWin32 automatycznie generuje poprawne podpisy, struktury, stałe i interfejsy COM na podstawie metadanych zestawu Windows SDK.
Wybierz podejście do interoperacyjności
| Approach | Kiedy stosować | Zalety | Cons |
|---|---|---|---|
| CsWin32 (zalecane) | Dowolne wywołanie natywnego interfejsu API Win32 z poziomu języka C# | Bezpieczne typowo, wygenerowane z oficjalnych metadanych pakietu Windows SDK, obsługuje marshalowanie i struktury, przyjazne dla AOT z konfiguracją | Wymaga pakietu NuGet; wygenerowany kod nie jest domyślnie widoczny |
| BibliotekaImportuj (.NET 7+) | Jednorazowe wywołania, w przypadku których znasz dokładną sygnaturę | Generowane ze źródła, zgodne z AOT, bez marshalingu w czasie wykonywania | Tworzysz i konserwujesz każdy podpis ręcznie |
| DllImport (starsza wersja) | Istniejący kod lub projekty platformy .NET | Działa wszędzie, bogaty zbiór przykładów od społeczności | Marshaling środowiska uruchomieniowego, sygnatury podatne na błędy |
| C#/WinRT | Interfejsy programowania aplikacji środowisko wykonawcze systemu Windows (Windows.*przestrzenie nazw) |
Przewidywane typy .NET, naturalne środowisko języka C# | Tylko dla API WinRT, a nie bezpośredniego Win32 |
Note
Domyślne dane wyjściowe generowane przez CsWin32 używają mechanizmu marshalingu środowiska uruchomieniowego platformy .NET i not są automatycznie zgodne z kompilacją AOT. W przypadku NativeAOT lub przycinania włącz CsWin32RunAsBuildTask i DisableRuntimeMarshalling—zobacz wskazówki dotyczące AOT dla CsWin32.
Tip
Jeśli potrzebny interfejs API znajduje się w Windows.* przestrzeni nazw (na przykład Windows.Storage lub Windows.Media), jest to interfejs API środowisko wykonawcze systemu Windows. Użyj projekcji WinRT zamiast P/Invoke. Zobacz Wywoływanie interfejsów API międzyoperacyjności z aplikacji .NET.
Wymagania wstępne
- Visual Studio 2022 (wersja 17.4 lub nowsza) lub zestaw SDK .NET 8 lub nowszy
- Istniejący projekt języka C# (WinUI 3, WPF, WinForms lub konsola)
Note
Platforma docelowa: .NET Framework czy .NET Standard? Ustaw <LangVersion>9</LangVersion> (lub nowszą wersję) w pliku projektu i dodaj pakiety NuGet System.Memory i System.Runtime.CompilerServices.Unsafe.
Krok 1. Instalowanie pakietu NuGet CsWin32
W katalogu projektu uruchom polecenie:
dotnet add package Microsoft.Windows.CsWin32
CsWin32 generuje kod, który używa wskaźników i niebezpiecznych kontekstów. Pakiet NuGet automatycznie włącza AllowUnsafeBlocks. Jeśli projekt jawnie ustawia <AllowUnsafeBlocks>false</AllowUnsafeBlocks>, usuń ten wiersz lub zmień go na true, w przeciwnym razie wygenerowany kod nie skompiluje się.
Krok 2. Żądanie potrzebnych interfejsów API
Utwórz plik o nazwie NativeMethods.txt w katalogu głównym projektu (obok .csproj pliku). Dodaj jedną nazwę interfejsu API na wiersz. W tym przewodniku zacznij od prostej funkcji:
GetTickCount
Zapisz plik. CsWin32 odczytuje go w czasie kompilacji i generuje odpowiednią otoczkę P/Invoke.
Krok 3. Wywoływanie wygenerowanego interfejsu API
Wygenerowany kod znajduje się w Windows.Win32 przestrzeni nazw w klasie statycznej o nazwie PInvoke. Wywołaj ją tak jak każda inna metoda statyczna:
using Windows.Win32;
// Get the number of milliseconds since the system started.
uint uptime = PInvoke.GetTickCount();
Console.WriteLine($"System uptime: {uptime} ms");
Skompiluj projekt. Jeśli nazwa funkcji w NativeMethods.txt jest prawidłowa, wywołanie kompiluje i uruchamia bez dodatkowej pracy.
Typowe pułapki
"Nie widzę wygenerowanego kodu"
CsWin32 jest generatorem źródłowym — jego dane wyjściowe nie są domyślnie wyświetlane jako pliki w projekcie. Aby sprawdzić wygenerowany kod:
- W Eksploratorze rozwiązań w programie Visual Studio rozwiń węzeł Zależności > Analizatory > Microsoft.Windows.CsWin32 > Microsoft.Windows.CsWin32.SourceGenerator.
- Alternatywnie ustaw
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>w pliku projektu, aby zapisać wygenerowane źródła w folderzeobj/.
Obiekt docelowy platformy AnyCPU
Kod wygenerowany przez csWin32 współdziała z platformą AnyCPU. Nie musisz zmieniać platformy docelowej w przypadku większości wywołań Win32.
Uzyskiwanie HWND w WinUI 3
Wiele interfejsów API Win32 wymaga uchwytu okna. W aplikacji WinUI 3 pobierz nazwę HWND z wystąpienia Window :
using WinRT.Interop;
var hWnd = WindowNative.GetWindowHandle(this);
Następnie przekaż hWnd (jako HWND lub nint) do funkcji Win32. Aby uzyskać szczegółowe informacje, zobacz Pobieranie uchwytu okna (HWND).
Dostosowywanie zachowania csWin32
Utwórz plik NativeMethods.json obok pliku tekstowego, aby kontrolować opcje generowania, takie jak szerokie i wąskie marshaling ciągów lub przyjazne przeciążenia:
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"emitSingleFile": false,
"public": true
}
Zobacz dokumentację konfiguracji CsWin32 , aby zapoznać się ze wszystkimi opcjami.
Następne kroki
- Wybierz podejście międzyoperacyjne — przewodnik po decyzjach dla wszystkich technik międzyoperacyjnych Windows
- Przewodnik: aplikacja WinUI 3 z międzyoperacyjnością Win32 — bardziej szczegółowy przykład dostosowywania paska tytułu przy użyciu csWin32
- CsWin32 na GitHub — źródło, przykłady i śledzenie problemów
- Platform Invoke (P/Invoke) — dokumentacja .NET dotycząca podstaw P/Invoke
- Wywoływanie interoperacyjnych interfejsów API z aplikacji platformy .NET — dla scenariuszy interoperacyjności opartych na modelu COM w środowisku WinRT (przekazywanie HWND, selektory itp.)