### Install Dependency Packages for .NET Framework/.NET Standard Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md For projects targeting .NET Framework 4.5+ or .NET Standard 2.0, install System.Memory and System.Runtime.CompilerServices.Unsafe for improved generated code. ```powershell dotnet add package System.Memory dotnet add package System.Runtime.CompilerServices.Unsafe ``` -------------------------------- ### Install CsWin32 NuGet Package Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md Use the .NET CLI to add the Microsoft.Windows.CsWin32 package to your project. ```powershell dotnet add package Microsoft.Windows.CsWin32 ``` -------------------------------- ### Get WMI Method Signature Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Retrieves the signature of the 'Start' method for the 'MSFT_MpScan' WMI class. This is necessary to understand the input and output parameters required for method invocation. ```cs classObj.GetMethod("Start", 0, out IWbemClassObject pInParamsSignature, out IWbemClassObject ppOutSignature); ``` -------------------------------- ### Add Required Packages Source: https://github.com/microsoft/cswin32/blob/main/src/Microsoft.Windows.CsWin32/readme.txt Install the System.Memory and System.Runtime.CompilerServices.Unsafe packages for .NET Framework or .NET Standard projects to improve generated code. Projects targeting .NET Core or .NET 5+ do not strictly require these but can install them harmlessly. ```powershell dotnet add package System.Memory dotnet add package System.Runtime.CompilerServices.Unsafe ``` -------------------------------- ### Update Win32 Metadata with NuGet Package Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md To use the latest metadata for code generation, install the `Microsoft.Windows.SDK.Win32Metadata` NuGet package. Use the `--prerelease` flag for pre-release versions. ```powershell dotnet add package Microsoft.Windows.SDK.Win32Metadata --prerelease ``` -------------------------------- ### Retrieve Last Write Time of a File Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Demonstrates how to get the last modification time of a file using P/Invoke. Requires GENERIC_ACCESS_RIGHTS and file handle operations. ```cs static void Main(string[] args) { Span szBuf = stackalloc char[(int)PInvoke.MAX_PATH]; if (args.Length is not 1) { Console.WriteLine("This sample takes a file name as a parameter\n"); return; } using SafeHandle hFile = PInvoke.CreateFile( args[0], (uint)GENERIC_ACCESS_RIGHTS.GENERIC_READ, FILE_SHARE_MODE.FILE_SHARE_READ, null, FILE_CREATION_DISPOSITION.OPEN_EXISTING, 0, null); if (hFile.IsInvalid) { Console.WriteLine("CreateFile failed with {0}\n", Marshal.GetLastPInvokeError()); return; } if (GetLastWriteTime(hFile, szBuf)) Console.WriteLine("Last write time is: {0}\n", szBuf.ToString()); } static unsafe bool GetLastWriteTime(SafeHandle hFile, Span lpszString) { FILETIME ftCreate, ftAccess, ftWrite; SYSTEMTIME stUTC, stLocal; // Retrieve the file times for the file. if (!PInvoke.GetFileTime(hFile, out ftCreate, out ftAccess, out ftWrite)) return false; // Convert the last-write time to local time. PInvoke.FileTimeToSystemTime(in ftWrite, out stUTC); PInvoke.SystemTimeToTzSpecificLocalTime(null, stUTC, out stLocal); // Build a string showing the date and time. string.Format("{0:00}/{1:00}/{2} {3:00}:{4:00}", stLocal.wMonth, stLocal.wDay, stLocal.wYear, stLocal.wHour, stLocal.wMinute) .AsSpan().CopyTo(lpszString); return true; } ``` -------------------------------- ### Get WMI Class Object Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Retrieves the IWbemClassObject for the 'MSFT_MpScan' class from the connected WMI services. This involves marshaling the class name and handling output parameters. ```cs var className = new SysFreeStringSafeHandle(Marshal.StringToBSTR("MSFT_MpScan"), true); IWbemClassObject? classObj = null; // out param services.GetObject(className, WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_RETURN_WBEM_COMPLETE, null, ref classObj, ref Unsafe.NullRef()); ``` -------------------------------- ### Build CustomIInspectable Project Source: https://github.com/microsoft/cswin32/blob/main/test/CustomIInspectable/readme.md Use 'dotnet msbuild' for building, as WinMDGenerator tasks require it. 'dotnet build' is not sufficient. ```bash dotnet restore dotnet msbuild ``` -------------------------------- ### Configure CsWin32 Settings Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md Use a NativeMethods.json file to configure settings like emitSingleFile. The $schema property provides editor completions and validation. ```json { "$schema": "https://aka.ms/CsWin32.schema.json", "emitSingleFile": false } ``` -------------------------------- ### Specify Win32 APIs in NativeMethods.txt Source: https://github.com/microsoft/cswin32/blob/main/src/Microsoft.Windows.CsWin32/README.md List the Win32 APIs you want to generate bindings for in a NativeMethods.txt file. Supporting types will be generated automatically. ```text CreateFile IUIRibbon S_OK NTSTATUS IsPwrHibernateAllowed ISpellChecker ``` -------------------------------- ### Use P/Invoke APIs with Optional Parameters and Span Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Demonstrates calling P/Invoke APIs, omitting optional parameters using named arguments, and using Span APIs for buffer management. ```cs using SafeHandle hDevInfo = PInvoke.SetupDiGetClassDevs( Flags: SETUP_DI_GET_CLASS_DEVS_FLAGS.DIGCF_ALLCLASSES | SETUP_DI_GET_CLASS_DEVS_FLAGS.DIGCF_PRESENT); var devInfo = new SP_DEVINFO_DATA { cbSize = (uint)sizeof(SP_DEVINFO_DATA) }; uint index = 0; while (PInvoke.SetupDiEnumDeviceInfo(hDevInfo, index++, ref devInfo)) { PInvoke.SetupDiGetDeviceInstanceId(hDevInfo, in devInfo, RequiredSize: out uint requiredSize); Span instanceIdSpan = new char[(int)requiredSize]; PInvoke.SetupDiGetDeviceInstanceId(hDevInfo, in devInfo, instanceIdSpan); Console.WriteLine($"Device {devInfo.ClassGuid} Instance ID: {instanceIdSpan.ToString()}"); } ``` -------------------------------- ### Create and Connect to WMI Namespace Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Instantiates the IWbemLocator COM object and connects to the \\ROOT\\Microsoft\\Windows\\Defender namespace. Requires proper handling of string marshaling and safe handles. ```cs // CoCreateInstance CLSID_WbemLocator IWbemLocator locator = WbemLocator.CreateInstance(); var ns = new SysFreeStringSafeHandle(Marshal.StringToBSTR(@"ROOT\Microsoft\Windows\Defender"), true); locator.ConnectServer(ns, new SysFreeStringSafeHandle(), new SysFreeStringSafeHandle(), new SysFreeStringSafeHandle(), 0, new SafeFileHandle(), null, out IWbemServices services); ``` -------------------------------- ### Define Extended Native Methods in MyApp.Helpers Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md This JSON configuration extends the existing PInvoke class from MyApp.Core, making the new P/Invoke declarations available as extension methods. The associated text file lists the native functions to be generated. ```json { "$schema": "https://aka.ms/CsWin32.schema.json", "className": "PInvokeHelpers", "extensionReceiver": "PInvoke", "public": true } ``` ```text GetForegroundWindow ``` -------------------------------- ### Include Metadata and Allowed Libraries in Props File Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/3rdPartyMetadata.md This XML snippet shows how to configure MSBuild items in a .props file to include a custom .winmd file for metadata and specify allowed native libraries that can be deployed with the app. ```xml ``` -------------------------------- ### Define Native Methods in MyApp.App Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md This JSON configuration defines another PInvoke class for the MyApp.App project. The associated text file lists the native functions to be generated. ```json { "$schema": "https://aka.ms/CsWin32.schema.json", "className": "PInvokeApp", "extensionReceiver": "PInvoke" } ``` ```text IsWindow ``` -------------------------------- ### Define Native Methods in MyApp.Core Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md This JSON configuration defines the P/Invoke class name and specifies that it should be public. The associated text file lists the native functions to be generated. ```json { "$schema": "https://aka.ms/CsWin32.schema.json", "className": "PInvoke", "public": true } ``` ```text GetTickCount ``` -------------------------------- ### Add Daily Build NuGet Feed Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md Add this package feed to your nuget.config file to consume daily builds. ```xml ``` -------------------------------- ### Create Shell Item (COM Wrappers, AOT-Compatible) Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Creates an IShellItem using COM wrappers, which is compatible with AOT compilation. The garbage collector manages the lifetime of the shell item. ```cs [STAThread] static unsafe void Main(string[] args) { HRESULT hr = PInvoke.SHCreateItemFromParsingName("C:\\Users\\you\\file.txt", null, typeof(IShellItem).GUID, out var ppv); if (hr.Failed) return; var shellItem = (IShellItem)ppv; // Let the GC to release shellItem } ``` -------------------------------- ### Extender Project Configuration for CsWin32 Composition Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md Configure extender projects' NativeMethods.json to set a unique className and specify the extensionReceiver. The extensionReceiver should be the className of the owner project. Ensure public is set appropriately if needed. ```json { "$schema": "https://aka.ms/CsWin32.schema.json", "className": "PInvokeMyLibrary", "extensionReceiver": "PInvoke", "public": true } ``` -------------------------------- ### Enable CsWin32 as a Build Task for NativeAOT Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md Configure your csproj to run CsWin32 as a build task before compilation, enabling support for NativeAOT and other source generators. It's recommended to also set DisableRuntimeMarshalling to true. ```xml true true ``` -------------------------------- ### Marshalling Enabled (Built-in COM Interop) Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Demonstrates using built-in COM Interop for marshalling. This method is not AOT-compatible. ```cs var fwMgr = (INetFwMgr)new NetFwMgr(); var authorizedApplications = fwMgr.LocalPolicy.CurrentProfile.AuthorizedApplications; var aaObjects = new object[authorizedApplications.Count]; var applicationsEnum = (IEnumVARIANT)authorizedApplications._NewEnum; applicationsEnum.Next((uint)authorizedApplications.Count, aaObjects, out uint fetched); foreach (var aaObject in aaObjects) { var app = (INetFwAuthorizedApplication)aaObject; Console.WriteLine("---"); Console.WriteLine($"Name: {app.Name.ToString()}"); Console.WriteLine($"Enabled: {(bool)app.Enabled}"); Console.WriteLine($"Remote Addresses: {app.RemoteAddresses.ToString()}"); Console.WriteLine($"Scope: {app.Scope}"); Console.WriteLine($"Process Image Filename: {app.ProcessImageFileName.ToString()}"); Console.WriteLine($"IP Version: {app.IpVersion}"); } ``` -------------------------------- ### Generated Extension Method Declaration for MyApp.Helpers Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md The CsWin32 tool generates this C# code, adding GetForegroundWindow as an extension method to the PInvoke class, based on the configuration and function list for MyApp.Helpers. ```csharp namespace Windows.Win32 { public static partial class PInvokeHelpers { extension (global::Windows.Win32.PInvoke) { [DllImport("USER32.dll", ExactSpelling = true)] public static extern global::Windows.Win32.Foundation.HWND GetForegroundWindow(); } } } ``` -------------------------------- ### Owner Project Configuration for CsWin32 Composition Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md Configure the owner project's NativeMethods.json to set the className and public flag. Setting public to true makes the receiver visible to extenders. This is typically done in the core or primitives project. ```json { "$schema": "https://aka.ms/CsWin32.schema.json", "className": "PInvoke", "public": true } ``` -------------------------------- ### Run tests with hardware filter Source: https://github.com/microsoft/cswin32/blob/main/CONTRIBUTING.md Execute project tests while excluding those that require specific hardware. This is useful for running tests in environments where hardware is not available. ```bash dotnet test --filter "TestCategory!=RequiresHardware" ``` -------------------------------- ### Create Shell Item (COM Interop, Not AOT-Compatible) Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Uses built-in COM Interop to create an IShellItem from a file path. This method is not compatible with Ahead-of-Time (AOT) compilation. ```cs [STAThread] static void Main(string[] args) { HRESULT hr = PInvoke.SHCreateItemFromParsingName("C:\\Users\\you\\file.txt", null, typeof(IShellItem).GUID, out var ppv); if (hr.Failed) return; var shellItem = (IShellItem)ppv; Marshal.ReleaseComObject(shellItem); } ``` -------------------------------- ### Target a Specific CPU Architecture in .csproj Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/ArchSpecificAPIs.md Add this property to your .csproj file to compile your project for a specific CPU architecture, enabling the generation of architecture-specific APIs. ```xml x64 ``` -------------------------------- ### Create Shell Item (Marshaling Disabled, AOT-Compatible) Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md An AOT-compatible method for creating an IShellItem by disabling marshaling and using raw pointers. Requires manual release of the COM object. ```cs [STAThread] static unsafe void Main(string[] args) { HRESULT hr; var IID_IShellItem = typeof(IShellItem).GUID; IShellItem* psi = null; fixed (char* pszPath = "C:\\Users\\you\\file.txt") hr = PInvoke.SHCreateItemFromParsingName(pszPath, null, &IID_IShellItem, (void**)&psi); if (hr.Failed) return; psi->Release(); } ``` -------------------------------- ### Marshalling Enabled (COM Wrappers, AOT Compatible) Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Shows COM wrappers for marshalling, which are AOT compatible. Note the use of `get_` methods and `ComVariant`. ```cs var fwMgr = NetFwMgr.CreateInstance(); var authorizedApplications = fwMgr.get_LocalPolicy().get_CurrentProfile().get_AuthorizedApplications(); var aaObjects = new ComVariant[authorizedApplications.get_Count()]; var applicationsEnum = (IEnumVARIANT)authorizedApplications.get__NewEnum(); applicationsEnum.Next((uint)authorizedApplications.get_Count(), aaObjects, out uint fetched); foreach (var aaObject in aaObjects) { var app = (INetFwAuthorizedApplication)ComVariantMarshaller.ConvertToManaged(aaObject)!; Console.WriteLine("---"); Console.WriteLine($"Name: {app.get_Name().ToString()}"); Console.WriteLine($"Enabled: {(bool)app.get_Enabled()}"); Console.WriteLine($"Remote Addresses: {app.get_RemoteAddresses().ToString()}"); Console.WriteLine($"Scope: {app.get_Scope()}"); Console.WriteLine($"Process Image Filename: {app.get_ProcessImageFileName().ToString()}"); Console.WriteLine($"IP Version: {app.get_IpVersion()}"); aaObject.Dispose(); } ``` -------------------------------- ### Accessing Extension Members via Host Class Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md Use the host class directly to access extension members in contexts like enum initializers or attribute arguments. This ensures correct resolution, especially in const contexts. ```csharp const uint Sentinel = PInvoke.WM_NULL; // host class on the owner enum MyFlags { Default = (int)PInvokeHelpers.SomeFlag } // host class on an extender ``` -------------------------------- ### Generated P/Invoke Declaration for MyApp.Core Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md The CsWin32 tool generates this C# code based on the NativeMethods.json and NativeMethods.txt files for the MyApp.Core project. ```csharp namespace Windows.Win32 { public static partial class PInvoke { [DllImport("KERNEL32.dll", ExactSpelling = true)] public static extern uint GetTickCount(); } } ``` -------------------------------- ### Enumerate Display Monitors (Marshaling Disabled) Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md An AOT-compatible version for enumerating display monitors. It uses a direct function pointer for the callback, avoiding standard marshaling. ```cs static unsafe void Main(string[] args) { BOOL fRes = PInvoke.EnumDisplayMonitors(HDC.Null, null, &MonitorEnumProc, 0); // ... } [UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])] static unsafe BOOL MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, RECT* lprcMonitor, LPARAM dwData) { // ... } ``` -------------------------------- ### Call Win32 API using PInvoke Source: https://github.com/microsoft/cswin32/blob/main/src/Microsoft.Windows.CsWin32/README.md Use the generated PInvoke methods to call Win32 APIs. Ensure you have the necessary using directives for types like SafeHandle and the API constants. ```csharp using SafeHandle f = PInvoke.CreateFile( "some.txt", (uint)GENERIC_ACCESS_RIGHTS.GENERIC_READ, FILE_SHARE_MODE.FILE_SHARE_READ, lpSecurityAttributes: null, FILE_CREATION_DISPOSITION.CREATE_ALWAYS, FILE_FLAGS_AND_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL, hTemplateFile: null); ``` -------------------------------- ### Use Span for Buffer and Size Parameters Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md For Win32 APIs with buffer and size parameters, CsWin32 generates overloads accepting Span when targeting frameworks that support it. This simplifies parameter passing. ```csharp BOOL IsTextUnicode(ReadOnlySpan lpv, Span lpiResult) ``` -------------------------------- ### Enumerate Display Monitors (Marshaling Enabled) Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Retrieves information about all connected display monitors using EnumDisplayMonitors. This version uses standard marshaling and is not AOT-compatible. ```cs static Dictionary _monitors = []; static unsafe MONITORENUMPROC proc = new(MonitorEnumProc); // Keep this alive static void Main(string[] args) { BOOL fRes = PInvoke.EnumDisplayMonitors(HDC.Null, (RECT?)null, proc, 0); if (!fRes) return; foreach (var monitor in _monitors) Console.WriteLine($"Device: {monitor.Key}, Rect: ({monitor.Value.Width},{monitor.Value.Height})"); } static unsafe BOOL MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, RECT* lprcMonitor, LPARAM dwData) { MONITORINFOEXW info = default; info.monitorInfo.cbSize = (uint)sizeof(MONITORINFO); PInvoke.GetMonitorInfo(hMonitor, (MONITORINFO*)&info); _monitors.Add(info.szDevice.ToString(), *lprcMonitor); return true; } ``` -------------------------------- ### Handle Optional Parameters in C# Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md CsWin32 generates two versions of methods with optional out/ref parameters: one omitting them and one including them. Use the version that best suits your needs. ```csharp // Omitting the optional parameter: IsTextUnicode(buffer); ``` ```csharp // Passing ref for optional parameter: IS_TEXT_UNICODE_RESULT result = default; IsTextUnicode(buffer, ref result); ``` -------------------------------- ### C# Constant Declaration and Forwarder Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md Demonstrates how CsWin32 emits constants in two forms: a static const on the host class and a forwarder property on the receiver type. The const is accessible in all contexts, while the forwarder is for runtime contexts. ```csharp public static partial class PInvoke { // 1. The real const lives on the host class. Reachable as `PInvoke.WM_NULL` in any context, // including enum initializers, attribute arguments, `fixed`-array sizes, and case labels. public const uint WM_NULL = 0u; extension (global::Windows.Win32.PInvoke) { // 2. A forwarder property surfaces the same value through the receiver type for runtime // contexts. `PInvoke.WM_NULL` resolves to this when not in a const context. public static uint WM_NULL => global::Windows.Win32.PInvoke.WM_NULL; } } ``` -------------------------------- ### Consuming P/Invoke Declarations in Application Code Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md This C# code demonstrates how to consume P/Invoke declarations generated by CsWin32 across different projects. The `using Windows.Win32;` directive makes all generated members, including extension methods, discoverable through the `PInvoke` symbol. ```csharp using Windows.Win32; uint ticks = PInvoke.GetTickCount(); // declared in MyApp.Core HWND hwnd = PInvoke.GetForegroundWindow(); // declared in MyApp.Helpers bool alive = PInvoke.IsWindow(hwnd); // declared in MyApp.App ``` -------------------------------- ### Merge Latest from Library.Template Source: https://github.com/microsoft/cswin32/blob/main/CONTRIBUTING.md Use this PowerShell script to fetch the latest changes from the main branch of the Library.Template and merge them into your current repository. Resolve any conflicts manually and then push the changes. ```powershell git fetch git checkout origin/main ./tools/MergeFrom-Template.ps1 # resolve any conflicts, then commit the merge commit. git push origin -u HEAD ``` -------------------------------- ### Pass Struct as Span Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Illustrates passing a struct to a method expecting a `Span` by using `Span` and `MemoryMarshal.AsBytes`. ```cs SHFILEINFOW fileInfo = default; PInvoke.SHGetFileInfo( "c:\\windows\\notepad.exe", FILE_FLAGS_AND_ATTRIBUTES.FILE_ATTRIBUTE_NORMAL, MemoryMarshal.AsBytes(new Span(ref fileInfo)), SHGFI_FLAGS.SHGFI_DISPLAYNAME); ``` -------------------------------- ### Check win32metadata package version Source: https://github.com/microsoft/cswin32/blob/main/CONTRIBUTING.md Use this PowerShell command to check if a new version of the win32metadata package is available on the msft_consumption feed. This is a crucial step before building after updating the MetadataVersion. ```pwsh $idx = Invoke-RestMethod "https://pkgs.dev.azure.com/azure-public/vside/_packaging/msft_consumption/nuget/v3/flat2/microsoft.windows.sdk.win32metadata/index.json" $idx.versions | Where-Object { $_ -like '*' } ``` -------------------------------- ### Handle Variable-Sized Structs with Span Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md APIs with variable-sized struct parameters, indicated by a [MemorySize] attribute, are projected as Span. This allows dynamic sizing based on other parameters. ```csharp // The cswin32 signature: static BOOL InitializeAcl(Span pAcl, ACE_REVISION dwAclRevision) { ... } ``` ```csharp // Make a buffer Span buffer = new byte[CalculateAclSize(...)]; InitializeAcl(buffer, ACE_REVISION.ACL_REVISION); // The beginning of the buffer is an ACL, so cast it to a ref: ref ACL acl = ref MemoryMarshal.AsRef(buffer); // Or treat it as a Span: Span aclSpan = MemoryMarshal.Cast(buffer); ``` -------------------------------- ### Access Generated P/Invoke Methods Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md After generating code, P/Invoke methods are accessible via the Windows.Win32.PInvoke class. Ensure you have the necessary using directive. ```csharp using Windows.Win32; PInvoke.CreateFile(/*args*/); ``` -------------------------------- ### Project Compilation Flags for Trimming and AOT Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md These MSBuild properties are used to enable trimming, NativeAOT compilation, and disabling the runtime marshaler for your C# project. ```xml true true true ``` -------------------------------- ### Convenience Overloads for Fixed-Size Structs Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md CsWin32 also generates struct-typed convenience overloads for APIs where the size is fixed (e.g., sizeof(T)). This is useful for APIs like SHGetFileInfo. ```csharp // Span overload: static nuint SHGetFileInfo(string pszPath, FILE_FLAGS_AND_ATTRIBUTES dwFileAttributes, Span psfi, SHGFI_FLAGS uFlags) ``` ```csharp // ref SHGETFILEINFOW overload: static nuint SHGetFileInfo(string pszPath, FILE_FLAGS_AND_ATTRIBUTES dwFileAttributes, ref SHFILEINFOW psfi, SHGFI_FLAGS uFlags) ``` -------------------------------- ### Set COM Proxy Blanket for Services Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/Examples.md Configures the security blanket for the COM service proxy using CoSetProxyBlanket. This is crucial for establishing appropriate authentication and impersonation levels, especially in AOT scenarios. ```cs unsafe { PInvoke.CoSetProxyBlanket( services, 10, // RPC_C_AUTHN_WINNT is 10 0, // RPC_C_AUTHZ_NONE is 0 pServerPrincName: null, dwAuthnLevel: RPC_C_AUTHN_LEVEL.RPC_C_AUTHN_LEVEL_CALL, dwImpLevel: RPC_C_IMP_LEVEL.RPC_C_IMP_LEVEL_IMPERSONATE, pAuthInfo: null, dwCapabilities: EOLE_AUTHENTICATION_CAPABILITIES.EOAC_NONE); } ``` -------------------------------- ### Disable Runtime Marshalling in CsWin32 Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/getting-started.md Configure CsWin32 to avoid code that relies on the runtime marshaler by setting allowMarshaling to false in NativeMethods.json. ```json { "$schema": "https://aka.ms/CsWin32.schema.json", "allowMarshaling": false } ``` -------------------------------- ### Qualifying Calls Within an Extension Block Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md When writing your own extension blocks, always qualify calls to sibling extension members with the receiver type. This prevents ambiguity and potential infinite recursion. ```csharp using Windows.Win32; namespace Windows.Win32; internal static class MyExtraHelpers { extension (PInvoke) { public static int RunWithCleanup() { // ✅ Qualify with the receiver. Anything else is wrong. uint t = PInvoke.GetTickCount(); return (int)t; } } } ``` -------------------------------- ### Rewrite XML Doc Cref References Source: https://github.com/microsoft/cswin32/blob/main/docfx/docs/composition.md When a cref points to an extension member, it cannot be resolved by XML doc tooling. Rewrite affected crefs to inline code using `` instead of ``. Leave direct member references unchanged. ```csharp /// PInvoke.GetTickCount ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.