# Microsoft WIL: header-only C++ wrappers for Windows APIs

> Microsoft WIL (Windows Implementation Library) is a header-only C++ library that wraps HANDLEs, HWNDs, registry keys and Win32 error codes in RAII and type-safe helpers. Here is how it installs, what it actually wraps, and where it stops helping.

**microsoft/wil** — Windows Implementation Library

- Repository: https://github.com/microsoft/wil
- Stars: 2,985 · Forks: 302
- Language: C++
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/microsoft-wil

## The Windows C++ problem WIL was written to remove

Win32 APIs report failure in several different ways. Some return a BOOL, some return an HRESULT, some return a HANDLE that is NULL or INVALID_HANDLE_VALUE on failure, and the actual reason often sits in GetLastError. WIL's result.h is described in the README as preprocessor macros that check for errors "in many of the myriad ways those errors are reported" and surface them as error codes or C++ exceptions. That is the core of the library: it does not replace Win32, it gives you one consistent way to ask whether a call worked and to hand the failure upward.

The audience is narrow on purpose. This is C++ code that already targets Windows, including code that uses exceptions and code that uses returned error codes. The README states that all of WIL can be used from user-space Windows code, and that some parts, such as the RAII resource wrappers, can be used in kernel mode. If you are writing portable C++ that must also build on Linux or macOS, WIL is the wrong dependency: every header it ships is about Windows types.

## Header-only, but not dependency-free: how the pieces fit

The repository is organised around include/wil/, with separate headers for separate concerns. resource.h holds smart pointers and auto-releasing wrappers for HANDLEs, HWNDs and other resource handles, following RAII semantics. win32_helpers.h covers the pattern where you call an API once to learn a required buffer size, allocate, then call again, and also handles casting and conversion between types. registry.h provides type-safe read, write and watch functions, including watchers that invoke a lambda or callback when a tree under the registry changes. network.h supplies a header-include list that resolves inter-header include dependencies, RAII objects for WSAStartup refcounts, RAII wrappers for addrinfo results, and a type-safe class for sockaddr structures. Tracelogging.h provides macros that emit telemetry through the TraceLogging API, viewable in Windows Performance Analyzer.

Because it is header-only, there is no link step and no runtime DLL to ship. That is also why the vcpkg instructions carry a caveat the README spells out: even though WIL is header-only, you still need to install the package for every architecture and platform you build for, otherwise WIL is not added to the include path for the missing ones.

## Installing WIL via vcpkg and using a resource wrapper

The repository does not document a build step for consumers, because there is nothing to build. The README lists two package managers and a third option: consume WIL directly from GitHub as a submodule, a symbolic link, or by downloading and copying files, following what it calls a "live at head" philosophy. The NuGet package is Microsoft.Windows.ImplementationLibrary and ships the headers plus a .targets file. The vcpkg port is named wil.

With vcpkg already set up, the README gives these two commands for the x86 and x64 Windows triplets:

```cmd
C:\vcpkg> vcpkg install wil:x86-windows
C:\vcpkg> vcpkg install wil:x64-windows
```

After that, WIL is on the include path for those triplets and you can include the headers directly. A minimal first use is a resource wrapper around a HANDLE, which is what resource.h exists for:

```cpp
#include <wil/resource.h>

void UseFile(HANDLE raw)
{
    wil::unique_handle file(raw);
    // file closes the handle when it leaves scope
}
```

The naming convention is visible across the headers: wil::unique_handle follows the same shape as the other unique_* wrappers, so once you have used one you can guess the rest. The README points to the GitHub wiki for documentation of the individual wrappers, and the wiki, not the README, is where the per-type detail lives.

## What the repository does not tell you

The README is a signpost, not a manual. It links each header to a wiki page and then stops. There is no API reference in the repository, no migration guide, and no statement about which Windows SDK versions the headers require. The prerequisites section is written for people building and testing WIL itself, not for people consuming it, which means a consumer looking for a minimum compiler version will not find one here.

Two other gaps are worth naming. First, the README does not document rollback or version pinning for consumers; the "live at head" advice and the periodic package updates, described as likely averaging once or twice per month, are the only guidance on staying current. Second, the error-handling macros in result.h are described at the level of intent, not behaviour, so the exact semantics of a given macro have to come from the wiki or the header source. That is a real cost for a team that wants a library it can adopt from the README alone.

## Where WIL stops being the right tool

WIL assumes you are already committed to Windows APIs and to C++. If your project is C, or if it is C++ but built with a non-MSVC toolchain on Windows, the library is not aimed at you: the build prerequisites list the latest MSVC build tools with Address Sanitizer components, the Windows SDK, and a recent Clang for the project's own test matrix, and the headers lean on Windows types and compiler behaviour throughout.

There is a second boundary. WIL wraps; it does not abstract away the platform. A team hoping to hide Win32 behind a portable interface will not get that from resource.h or win32_helpers.h, because the types in the signatures are Windows types. The library shortens the distance between you and the API. It does not remove the API. Teams that want a portable threading, file or networking layer should be looking at a cross-platform library instead, and using WIL only in the Windows-specific layer underneath it.

## WIL against the Guidelines Support Library

The most common comparison in search traffic is with Microsoft's GSL. The two libraries overlap in name recognition and almost nowhere else. GSL is about C++ language-level safety: it supplies types and annotations such as span and not_null that express contracts in portable C++ and are not tied to any operating system. WIL is about operating-system-level safety: it supplies RAII wrappers around Windows resource handles, type-safe registry access, Winsock helpers and error-checking macros for Win32 return conventions.

A Windows codebase can reasonably use both, and the choice between them is not either/or. If you need to express that a pointer is never null, GSL is the tool. If you need a HANDLE to close itself, or a registry read that returns a typed value, WIL is the tool. Neither one substitutes for the other, and neither one is a general-purpose utility library.

## Maintenance, licensing and the cost of staying current

The repository is not archived, and the last push was on 2026-09-20. Releases are infrequent relative to commits: v1.0.260126.7 is dated 2026-01-26, the release before it 2025-03-25, and the one before that 2024-08-05. The README's own estimate for package manager updates, roughly once or twice per month, describes the cadence of the packaged copies rather than the tagged releases, and those two things can drift apart.

Because WIL is header-only, upgrading means replacing headers, not relinking a binary, which keeps the mechanical cost low. The real cost is behavioural: if you consume from head, you take whatever the source contains at the moment you pull, and the README offers no compatibility policy for that path. Pinning to a NuGet or vcpkg version is the more predictable option, at the price of waiting for the package to catch up. The licence is MIT, and the repository carries a LICENSE file and a ThirdPartyNotices.txt; if you redistribute WIL inside a product, read both rather than assuming the MIT identifier covers every file in the tree.

## Conclusion

Adopt WIL if you write Windows C++ that manages raw HANDLEs, HWNDs, registry keys or error codes and you want RAII cleanup plus type-safe wrappers without a build dependency, since it is header-only and MIT licensed. Do not adopt it for cross-platform code or for a non-MSVC toolchain, and do not expect the repository to tell you how to consume it beyond NuGet, vcpkg, or copying the include directory. Before you commit, check the licence file and ThirdPartyNotices.txt against your own distribution terms, and confirm that your compiler and Windows SDK are recent enough for the headers you plan to include.

## FAQ

### Is Microsoft WIL a compiled library I have to link against?

No. The README describes WIL as a header-only C++ library, and the NuGet package ships the headers under the include directory plus a .targets file. There is no runtime component to link or ship.

### How do I install Microsoft WIL with vcpkg?

The README gives the commands vcpkg install wil:x86-windows and vcpkg install wil:x64-windows. It notes that even though WIL is header-only, you still need to install the package for every architecture and platform you build for, or it will not be added to the include path for the missing ones.

### What does Microsoft WIL include besides resource wrappers?

The README lists resource.h for RAII wrappers around HANDLEs and HWNDs, win32_helpers.h for buffer-size and conversion helpers, registry.h for type-safe registry reads, writes and watchers, network.h for Winsock and sockaddr handling, result.h for error-checking macros, and Tracelogging.h for telemetry macros.

### Can Microsoft WIL be used in kernel mode?

The README states that all of WIL can be used from user-space Windows code, and that some parts, such as the RAII resource wrappers, can even be used in kernel mode. It does not enumerate which other headers are kernel-safe.

### Where is Microsoft WIL documented?

The README says the project is documented in its GitHub wiki, and each header listing in the README links to a wiki page such as RAII resource wrappers or Error-handling helpers. The repository itself has no API reference.

## Sources

- [Issues](https://github.com/microsoft/wil/issues)
- [License: MIT](https://github.com/microsoft/wil/blob/master/LICENSE)
- [microsoft/wil on GitHub](https://github.com/microsoft/wil)
- [README](https://github.com/microsoft/wil/blob/master/README.md)
- [Releases](https://github.com/microsoft/wil/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/microsoft-wil
