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

  1. 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>.
  2. Lifetime: using ComScope<T> scope = new(); for every transient COM pointer (CoCreateInstance, QueryInterface, IEnumXxx::Next, factory output, app-local STDAPI Get*, etc.). Never write T* local; try { ... } finally { local->Release(); } — that's the pre-ComScope shape that leaks on every early return. Same for BSTR out-params: using BSTR x = default;.
  3. Activate via ComClassFactory.TryCreate(CLSID, ...) (AOT-compatible) or PInvoke.CoCreateInstance with IID.Get<T>() — not &localGuid.
  4. Call via scope.Pointer->Method(...). Pass ComScope<T> directly where the API expects T** / void** — the implicit operator does the address-of.
  5. Match the caller's error contract. If the top-level consumer swallows COM failure ("no result" == "absent"), helpers return default / false instead of throwing a COMException that's immediately discarded. ThrowOnFailure only when the exception will actually propagate or assert a should-never-happen.
  6. Guard with #if FEATURE_WINDOWSINTEROP — add && NET only when the struct uses the static-abstract IComIID form 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):

Installs
2
Repository
dotnet/msbuild
GitHub Stars
5.5K
First Seen
Jun 4, 2026
cswin32-com — dotnet/msbuild