Windows Implementation Libraries (WIL)
repository·master·Indexed 25 days ago
https://github.com/microsoft/wilA header-only C++ library providing type-safe, RAII-based wrappers for common Windows API patterns. WIL includes specialized headers for resource management (HANDLEs, HWNDs), registry access, networking, Win32 API helpers, and telemetry via TraceLogging. It supports multiple error handling strategies, including exception-based, error-code-based (HRESULT), and fail-fast behaviors, and provides the wil::com_ptr class for simplified COM pointer management.
What's inside WIL
- Windows Implementation Libraries (WIL) is a header-only C++ library designed to provide readable, type-safe C++ interfaces for common Windows coding patterns. It supports both C++ exception-based error handling and error-code-based reporting. WIL can be used in user-space Windows code, and certain components like RAII resource wrappers are compatible with kernel mode.
Understand WIL Namespaces
masterWIL provides functionality through two primary namespaces:
wil::: Contains all standard WIL classes and functions.wistd::: Contains core C++ concepts from the STL for callers not using the standard library. This namespace mirrorsstd::functionality with almost no modification.
Note: If your project uses exceptions, you should always prefer the
std::counterparts overwistd::.Install WIL via NuGet
masterYou can consume WIL as a NuGet package. The packageMicrosoft.Windows.ImplementationLibraryincludes the necessary header files and a.targetsfile for integration.Format code using the Ninja build target
masterIf you have already configured the build environment, you can invoke the formatting script via the
formatbuild target using Ninja.C:\wil\build\clang-x64-debug> ninja formatEnable RoOriginateError for WinRT components
masterTo ensure that the full call stack is observed from the point where an error is first encountered (especially useful for WinRT components), you can opt into
RoOriginateErrorbehavior.Include the following header exactly once per DLL to automate this for return-based or exception-based errors encountered by WIL macros.
#include <wil\result_o_riginate.h>Handle Agile and Weak COM references
masterWIL provides specialized types and functions to handle weak and agile references. All
queryandcopyroutines resolve references when used againstIWeakReferenceorIAgileReference.Key Types:
wil::com_weak_ref: An alias for acom_ptracting as a weak reference.wil::com_agile_ref: An alias for acom_ptracting as an agile reference.wil::com_agile_ref_failfast: An agile reference that crashes on failure.
Usage Pattern:
- Stash the reference using
wil::com_weak_query(ptr)orwil::com_agile_query_failfast(ptr). - Resolve the reference using
.query<T>()or stand-alonewil::com_query_to_nothrow(...)functions.
HRESULT WeakOrAgile(IUnknown* unknown) { wil::com_weak_ref weakRef; wil::com_agile_ref_failfast agileRef; // Stash references weakRef = wil::com_weak_query(unknown); agileRef = wil::com_agile_query_failfast(unknown); // Resolve references and use weakRef.query<IFoo>()->Method1(); wil::com_ptr_nothrow<IFoo> foo; RETURN_IF_FAILED(wil::com_query_to_nothrow(agileRef, &foo)); foo->Method1(); return S_OK; }Install Prerequisites via WinGet
masterYou can install the necessary development tools for WIL using WinGet in a PowerShell console:
winget install Microsoft.VisualStudio.2022.Community winget install Microsoft.WindowsSDK.10.0.22621 winget install Microsoft.NuGet -e winget install Kitware.CMake -e winget install Ninja-build.Ninja -e # Select "Add LLVM to the system path for all users" winget install -i llvm.llvmBuild the WIL project from source
masterTo ensure full coverage of the project, you can initialize, build, and test the entire repository using the provided scripts. Run these commands from the root of the repository directory.
C:\wil> scripts\init_all.cmd C:\wil> scripts\build_all.cmd C:\wil> scripts\runtests.cmdInstall WIL via vcpkg
masterWIL is available via vcpkg under the name
wil. Because WIL is header-only, you must install the package for every architecture/platform you intend to target to ensure the include paths are correctly configured.C:\vcpkg> vcpkg install wil:x86-windows C:\vcpkg> vcpkg install wil:x64-windowsPerform COM queries with com_ptr
masterWIL provides several ways to query COM interfaces from a
com_ptr<T>. The choice depends on how you want to handle null pointers and errors.Query vs Copy
query<T>()/query_to(T**): Produces an error if the interface is unsupported. Crashes if the source pointer is null.copy<T>()/copy_to(T**): Produces an error if the interface is unsupported. Returns null (preserves null) if the source pointer is null.try_query<T>()/try_query_to(T**): Never produces an error. Returnstrueor a valid pointer only if supported. Crashes if the source pointer is null.try_copy<T>()/try_copy_to(T**): Never produces an error. Returnstrueor a valid pointer only if supported. Returns null (preserves null) if the source pointer is null.
Output Patterns
- Direct Return:
m_ptr.query<IFoo>()returns acom_ptrof the queried type. - Typed Out Parameter:
m_ptr.query_to(&ptr)deduces the IID from the parameter type. - IID and PPV:
m_ptr.query_to(IID_IFoo, &ptr)uses the explicit IID andvoid**pattern.
Format changes against a specific commit
masterTo format all changes relative to a specific branch or commit (e.g., after merging
upstream/master), use the providedformat-changes.cmdscript. This script uses the version ofclang-formatthat ships with Visual Studio to ensure consistency.C:\wil> git fetch upstream C:\wil> git merge upstream/master C:\wil> scripts\format-changes.cmd upstream/masterBuild WIL using CMake Presets
masterIf you have the prerequisites installed, you can use CMake presets to configure and build the project from a native command window (e.g.,
x64 Native Tools Command Prompt for VS 2022).# Configure for clang compiler, then build clang-debug C:\wil> cmake --preset "clang" C:\wil> cmake --build --preset "clang-debug" # Build for MSVC release, all targets C:\wil> cmake --build --preset "msvc-release" # Build only one test (e.g. for improved compile times) C:\wil> cmake --build --preset "msvc-release" --target "witest.noexcept" # Run tests C:\wil> ctest --preset "msvc-release"