Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il modo consigliato per chiamare le API Win32 da C# è CsWin32, un generatore di codice sorgente che produce wrapper P/Invoke con controllo dei tipi durante la compilazione. CsWin32 funziona con qualsiasi tipo di progetto C#, WinUI 3, macchine virtuali Windows, WinForms, console o libreria di classi ed elimina la necessità di scrivere DllImportLibraryImport o dichiarazioni a mano.
Vengono elencati i nomi delle funzioni Win32 necessari in un file di testo e CsWin32 genera automaticamente le firme, gli struct, le costanti e le interfacce COM corrette dai metadati di Windows SDK.
Scegliere un approccio di interoperabilità
| Avvicinarsi | Quando utilizzare | Pros | Svantaggi |
|---|---|---|---|
| CsWin32 (scelta consigliata) | Qualunque chiamata all'API Win32/nativa da C# | Indipendente dai tipi, generato dai metadati ufficiali di Windows SDK, gestisce il marshalling e gli struct, AOT-friendly con la configurazione | Richiede il pacchetto NuGet; il codice generato non è visibile per impostazione predefinita |
| LibraryImport (.NET 7+) | Chiamate una tantum in cui si conosce la firma esatta | Generato dal codice sorgente, compatibile con AOT, senza marshalling in fase di esecuzione | Si scrive e si mantiene ogni firma manualmente |
| DllImport (versione legacy) | Codice esistente o progetti .NET Framework | Funziona ovunque, numerosi esempi di community | Marshalling in fase di esecuzione, firme soggette a errori |
| C#/WinRT | API di Windows Runtime (namespace Windows.*) |
Tipi di .NET proiettati, esperienza C# naturale | Solo per le API WinRT, non per Win32 puro |
Note
L'output predefinito di CsWin32 usa il marshaller di runtime .NET e non è compatibile automaticamente con AOT. Per NativeAOT o il trimming, abilita CsWin32RunAsBuildTask e DisableRuntimeMarshalling: consulta la guida AOT di CsWin32.
Tip
Se l'API necessaria si trova in uno Windows.* spazio dei nomi (ad esempio, Windows.Storage o Windows.Media), si tratta di un'API Windows Runtime. Usare una proiezione WinRT anziché P/Invoke. Vedere Chiamare le API di interoperabilità da un'app .NET.
Prerequisiti
- Visual Studio 2022 (versione 17.4 o successiva) o .NET 8+ SDK
- Progetto C# esistente (WinUI 3, macchine virtuali Windows, WinForms o console)
Note
Hai come destinazione .NET Framework o .NET Standard? Impostare <LangVersion>9</LangVersion> (o versione successiva) nel file di progetto, e aggiungere i pacchetti NuGet System.Memory e System.Runtime.CompilerServices.Unsafe.
Passaggio 1: Installare il pacchetto NuGet CsWin32
Nella directory del progetto, esegui:
dotnet add package Microsoft.Windows.CsWin32
CsWin32 genera codice che usa puntatori e contesti non sicuri. Il pacchetto NuGet abilita automaticamente AllowUnsafeBlocks. Se il progetto imposta <AllowUnsafeBlocks>false</AllowUnsafeBlocks>in modo esplicito , rimuovere tale riga o modificarla in true, altrimenti il codice generato non verrà compilato.
Passaggio 2: Richiedere le API necessarie
Creare un file denominato NativeMethods.txt nella radice del progetto (accanto al .csproj file). Aggiungere un nome API per riga. Per questa procedura dettagliata, iniziare con una funzione semplice:
GetTickCount
Salva il file. CsWin32 lo legge in fase di compilazione e genera il wrapper P/Invoke corrispondente.
Passaggio 3: Chiamare l'API generata
Il codice generato risiede nello spazio dei nomi Windows.Win32, all'interno di una classe statica denominata PInvoke. Chiamarlo come qualsiasi altro metodo statico:
using Windows.Win32;
// Get the number of milliseconds since the system started.
uint uptime = PInvoke.GetTickCount();
Console.WriteLine($"System uptime: {uptime} ms");
Crea il progetto. Se il nome della funzione in NativeMethods.txt è valido, la chiamata viene compilata ed eseguita senza ulteriori operazioni.
Problemi comuni
"Non è possibile visualizzare il codice generato"
CsWin32 è un generatore di codice sorgente: il relativo output non appare come file nel tuo progetto per impostazione predefinita. Per esaminare il codice generato:
- In Visual Studio espandere Dependencies > Analyzers > Microsoft.Windows. CsWin32 > Microsoft.Windows. CsWin32.SourceGenerator in Esplora soluzioni.
- In alternativa, imposta
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>nel file di progetto per scrivere i file sorgente generati nella cartellaobj/.
Destinazione della piattaforma AnyCPU
Il codice generato da CsWin32 funziona con AnyCPU. Non è necessario modificare la destinazione della piattaforma per la maggior parte delle chiamate Win32.
Ottenere un HWND in WinUI 3
Molte API Win32 richiedono un handle di finestra. In un'app WinUI 3, ottieni l'HWND dalla tua istanza Window:
using WinRT.Interop;
var hWnd = WindowNative.GetWindowHandle(this);
Quindi passare hWnd (come HWND o nint) alla funzione Win32. Per ulteriori dettagli, vedere Recuperare un handle di finestra (HWND).
Personalizzazione del comportamento di CsWin32
Crea un file NativeMethods.json accanto al file di testo per controllare le opzioni di generazione, ad esempio il marshalling di stringhe wide o narrow oppure gli overload semplificati:
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"emitSingleFile": false,
"public": true
}
Per tutte le opzioni, vedere le informazioni di riferimento sulla configurazione di CsWin32 .
Passaggi successivi
- Scegliere l'approccio di interoperabilità: guida decisionale per tutte le tecniche di interoperabilità Windows
- Procedura dettagliata: App WinUI 3 con interoperabilità Win32 , un esempio più approfondito che personalizza una barra del titolo usando CsWin32
- CsWin32 su GitHub : origine, esempi e strumento di rilevamento dei problemi
- Platform Invoke (P/Invoke) - documentazione .NET sui concetti fondamentali di P/Invoke
- Chiamare API di interoperabilità da un'app .NET — per scenari di interoperabilità WinRT basati su COM (passaggio di HWND, selettori e così via)