cswin32-com
Installation
SKILL.md
CsWin32 COM Interop Guide
Struct-based COM interop using CsWin32 patterns — AOT-compatible, no [ComImport] or built-in marshalling.
Paired skill: cswin32-interop covers general P/Invoke and the blittable signature rules that apply to both [DllImport] and COM vtables. This file covers only the COM-specific layer.
Workflow
- Interface in Win32 metadata? Add the name to
src/Framework/NativeMethods.txt→ CsWin32 generates it. Not in metadata (WMI, Fusion, Setup Configuration) → define a manual struct under its own folder, excluded from source builds via<Compile Remove>. - Lifetime:
using ComScope<T> scope = new();for every transient COM pointer (CoCreateInstance,QueryInterface,IEnumXxx::Next, factory output, app-localSTDAPI Get*, etc.). Never writeT* local; try { ... } finally { local->Release(); }— that's the pre-ComScopeshape that leaks on every early return. Same forBSTRout-params:using BSTR x = default;. - Activate via
ComClassFactory.TryCreate(CLSID, ...)(AOT-compatible) orPInvoke.CoCreateInstancewithIID.Get<T>()— not&localGuid. - Call via
scope.Pointer->Method(...). PassComScope<T>directly where the API expectsT**/void**— the implicit operator does the address-of. - Match the caller's error contract. If the top-level consumer swallows COM failure ("no result" == "absent"), helpers return
default/falseinstead of throwing aCOMExceptionthat's immediately discarded.ThrowOnFailureonly when the exception will actually propagate or assert a should-never-happen. - Guard with
#if FEATURE_WINDOWSINTEROP— add&& NETonly when the struct uses the static-abstractIComIIDform exclusively (no net472 dual-target).
Manual COM Structs (Not in Metadata)
Define each interface in its own file under e.g. src/Tasks/AssemblyDependency/Fusion/, src/Framework/Shared/VisualStudio/, src/Framework/Utilities/Wmi/. Exclude from source builds. Pattern (dual-target — works on net472 + .NET):