Memanggil API Win32 dari aplikasi C# Windows

Cara yang disarankan untuk memanggil API Win32 dari C# adalah CsWin32, generator sumber yang menghasilkan pembungkus P/Invoke yang aman jenis pada waktu kompilasi. CsWin32 dapat digunakan dengan jenis proyek C# apa pun—WinUI 3, WPF, WinForms, aplikasi konsol, atau pustaka kelas—dan menghilangkan kebutuhan untuk menulis sendiri deklarasi DllImport atau LibraryImport secara manual.

Anda mencantumkan nama fungsi Win32 yang Anda butuhkan dalam file teks, dan CsWin32 menghasilkan tanda tangan, struktur, konstanta, dan antarmuka COM yang benar secara otomatis dari metadata SDK Windows.

Pilih pendekatan interop

Approach Kapan digunakan Pros Cons
CsWin32 (disarankan ) Setiap panggilan API Win32/native dari C# Aman terhadap tipe, dihasilkan dari metadata SDK Windows resmi, menangani marshaling dan struktur, ramah AOT dengan konfigurasi Memerlukan paket NuGet; kode yang dihasilkan tidak terlihat secara default
LibraryImport (.NET 7+) Panggilan sekali pakai di mana Anda mengetahui tanda tangan yang tepat Dihasilkan dari sumber, kompatibel dengan AOT, tanpa marshaling saat runtime Anda menulis dan memelihara setiap tanda tangan secara manual
DllImport (warisan) Kode yang ada, atau proyek .NET Framework Bekerja di mana saja, contoh komunitas yang luas Marshaling saat runtime, signature yang rawan kesalahan
C#/WinRT API Windows Runtime (Windows.* ruang nama) Jenis .NET yang diproyeksikan, pengalaman C# alami Hanya untuk API WinRT, bukan Win32 mentah

Note

Output bawaan CsWin32 menggunakan marshaller runtime .NET dan tidak secara otomatis kompatibel dengan AOT. Untuk NativeAOT atau pemangkasan, aktifkan CsWin32RunAsBuildTask dan DisableRuntimeMarshalling—lihat panduan CsWin32 AOT.

Tip

Jika API yang Anda butuhkan berada di Windows.* namespace layanan (misalnya, Windows.Storage atau Windows.Media), api tersebut adalah API Windows Runtime. Gunakan proyeksi WinRT alih-alih P/Invoke. Lihat Memanggil API interop dari aplikasi .NET.

Prasyarat

  • Visual Studio 2022 (versi 17.4 atau yang lebih baru) atau .NET 8+ SDK
  • Proyek C# yang ada (WinUI 3, WPF, WinForms, atau konsol)

Note

Menargetkan .NET Framework atau .NET Standard? Atur <LangVersion>9</LangVersion> (atau yang lebih baru) di file proyek Anda, dan tambahkan paket NuGet System.Memory dan System.Runtime.CompilerServices.Unsafe.

Langkah 1: Instal paket CsWin32 NuGet

Di direktori proyek Anda, jalankan:

dotnet add package Microsoft.Windows.CsWin32

CsWin32 menghasilkan kode yang menggunakan penunjuk dan konteks yang tidak aman. Paket NuGet diaktifkan AllowUnsafeBlocks secara otomatis. Jika proyek Anda secara eksplisit mengatur <AllowUnsafeBlocks>false</AllowUnsafeBlocks>, hapus baris tersebut atau ubah menjadi true, jika tidak, kode yang dihasilkan tidak akan dikompilasi.

Langkah 2: Minta API yang Anda butuhkan

Buat file dengan nama NativeMethods.txt di direktori root proyek Anda (di sebelah file .csproj). Tambahkan satu nama API per baris. Untuk panduan ini, mulailah dengan fungsi sederhana:

GetTickCount

Simpan file tersebut. CsWin32 membacanya pada waktu kompilasi dan menghasilkan pembungkus P/Invoke yang cocok.

Langkah 3: Panggil API yang dihasilkan

Kode yang dihasilkan berada dalam namespace Windows.Win32 di bawah kelas statis bernama PInvoke. Sebut saja seperti metode statis lainnya:

using Windows.Win32;

// Get the number of milliseconds since the system started.
uint uptime = PInvoke.GetTickCount();
Console.WriteLine($"System uptime: {uptime} ms");

Bangun proyek Anda. Jika nama fungsi di NativeMethods.txt valid, panggilan mengkompilasi dan berjalan tanpa pekerjaan tambahan.

Kesalahan Umum

"Saya tidak dapat melihat kode yang dihasilkan"

CsWin32 adalah generator sumber—outputnya tidak muncul sebagai file di proyek Anda secara default. Untuk memeriksa kode yang dihasilkan:

  1. Di Visual Studio, perluas Dependensi > Penganalisis > Microsoft.Windows.CsWin32 > Microsoft.Windows.CsWin32.SourceGenerator di Penjelajah Solusi.
  2. Atau, atur <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> dalam file proyek Anda untuk menulis sumber yang dihasilkan ke obj/ folder.

Platform target AnyCPU

Kode yang dihasilkan CsWin32 berfungsi dengan AnyCPU. Anda tidak perlu mengubah target platform untuk sebagian besar panggilan Win32.

Mendapatkan HWND di WinUI 3

Banyak API Win32 memerlukan handle jendela. Dalam aplikasi WinUI 3, dapatkan HWND dari instans Anda Window :

using WinRT.Interop;

var hWnd = WindowNative.GetWindowHandle(this);

Kemudian teruskan hWnd (sebagai HWND atau nint) ke fungsi Win32. Lihat Mengambil handle jendela (HWND) untuk detail lebih lanjut.

Menyesuaikan perilaku CsWin32

Buat file NativeMethods.json di samping file teks Anda untuk mengontrol opsi pembuatan seperti marshaling string lebar-vs-sempit atau kelebihan beban yang ramah:

{
  "$schema": "https://aka.ms/CsWin32.schema.json",
  "emitSingleFile": false,
  "public": true
}

Lihat referensi konfigurasi CsWin32 untuk semua opsi.

Langkah berikutnya