Windows Implementation Libraries (WIL)

repository·master·Indexed 25 days ago

https://github.com/microsoft/wil

A 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.

Tokens
3.5K
Snippets
12
Records
21
Agent score
34%

What's inside WIL

  1. Overview of Windows Implementation Libraries (WIL)

    master
    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.
  2. Understand WIL Namespaces

    master

    WIL 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 mirrors std:: functionality with almost no modification.

    Note: If your project uses exceptions, you should always prefer the std:: counterparts over wistd::.

  3. Format code using the Ninja build target

    master

    If you have already configured the build environment, you can invoke the formatting script via the format build target using Ninja.

    C:\wil\build\clang-x64-debug> ninja format
  4. Enable RoOriginateError for WinRT components

    master

    To 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 RoOriginateError behavior.

    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>
  5. Handle Agile and Weak COM references

    master

    WIL provides specialized types and functions to handle weak and agile references. All query and copy routines resolve references when used against IWeakReference or IAgileReference.

    Key Types:

    • wil::com_weak_ref: An alias for a com_ptr acting as a weak reference.
    • wil::com_agile_ref: An alias for a com_ptr acting as an agile reference.
    • wil::com_agile_ref_failfast: An agile reference that crashes on failure.

    Usage Pattern:

    1. Stash the reference using wil::com_weak_query(ptr) or wil::com_agile_query_failfast(ptr).
    2. Resolve the reference using .query<T>() or stand-alone wil::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;
    }
  6. Install Prerequisites via WinGet

    master

    You 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.llvm
  7. Build the WIL project from source

    master

    To 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.cmd
  8. Install WIL via vcpkg

    master

    WIL 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-windows
  9. Perform COM queries with com_ptr

    master

    WIL 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. Returns true or a valid pointer only if supported. Crashes if the source pointer is null.
    • try_copy<T>() / try_copy_to(T**): Never produces an error. Returns true or a valid pointer only if supported. Returns null (preserves null) if the source pointer is null.

    Output Patterns

    1. Direct Return: m_ptr.query<IFoo>() returns a com_ptr of the queried type.
    2. Typed Out Parameter: m_ptr.query_to(&ptr) deduces the IID from the parameter type.
    3. IID and PPV: m_ptr.query_to(IID_IFoo, &ptr) uses the explicit IID and void** pattern.
  10. Format changes against a specific commit

    master

    To format all changes relative to a specific branch or commit (e.g., after merging upstream/master), use the provided format-changes.cmd script. This script uses the version of clang-format that 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/master
  11. Build WIL using CMake Presets

    master

    If 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"