Top Related Projects
Guidelines Support Library
Abseil Common Libraries (C++)
Super-project for modularized Boost
An open-source C++ library developed and used at Facebook.
GoogleTest - Google Testing and Mocking Framework
A modern formatting library
Quick Overview
The Windows Implementation Library (WIL) is a header-only C++ library developed by Microsoft for Windows development. It provides a set of C++ interfaces and implementations for common Windows programming patterns and idioms, making it easier to write correct, safe, and efficient code.
Pros
- Simplifies Windows API usage with modern C++ abstractions
- Improves code safety and reduces common programming errors
- Header-only library, easy to integrate into existing projects
- Actively maintained by Microsoft with regular updates
Cons
- Primarily focused on Windows development, limiting cross-platform use
- Learning curve for developers unfamiliar with WIL patterns
- May introduce additional complexity for simple projects
- Some features require Windows 10 or later
Code Examples
- Using RAII for handle management:
#include <wil/resource.h>
wil::unique_handle fileHandle{CreateFile(L"example.txt", GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)};
THROW_LAST_ERROR_IF(!fileHandle);
// Handle is automatically closed when fileHandle goes out of scope
- Error handling with WIL:
#include <wil/result.h>
HRESULT DoSomething()
{
RETURN_IF_FAILED(SomeWindowsFunction());
RETURN_HR_IF(E_INVALIDARG, someCondition);
return S_OK;
}
- Using WIL's string helpers:
#include <wil/string.h>
wil::unique_cotaskmem_string str;
THROW_IF_FAILED(SHGetKnownFolderPath(FOLDERID_Desktop, 0, nullptr, &str));
std::wcout << str.get() << std::endl;
Getting Started
To use WIL in your project:
- Clone the repository or download the latest release from GitHub.
- Add the
include
directory to your project's include paths. - Include the necessary WIL headers in your code:
#include <wil/resource.h>
#include <wil/result.h>
#include <wil/win32_helpers.h>
// Your code here
- Compile your project with C++17 or later standard enabled.
Competitor Comparisons
Guidelines Support Library
Pros of GSL
- Provides a more comprehensive set of guidelines and utilities for C++ programming
- Offers a broader range of safety and correctness features, including span and string_span
- Has wider industry adoption and recognition as a C++ coding standard
Cons of GSL
- May have a steeper learning curve due to its more extensive feature set
- Can introduce additional dependencies and complexity to projects
- May have performance overhead in some cases due to added safety checks
Code Comparison
GSL:
gsl::span<int> safe_array(arr, arr_size);
for (const auto& element : safe_array) {
// Safe iteration over array elements
}
WIL:
wil::unique_handle file_handle;
RETURN_IF_WIN32_BOOL_FALSE(CreateFile2(..., &file_handle));
// Automatic resource management
Summary
GSL focuses on providing a comprehensive set of guidelines and utilities for C++ programming, emphasizing safety and correctness. WIL, on the other hand, is specifically designed for Windows development, offering lightweight abstractions and error-handling mechanisms tailored to the Windows API. While GSL has broader applicability and industry recognition, WIL excels in simplifying Windows-specific development tasks and resource management.
Abseil Common Libraries (C++)
Pros of Abseil
- Broader platform support, including Linux and macOS
- More comprehensive library with additional data structures and utilities
- Active development with frequent updates and contributions
Cons of Abseil
- Larger codebase, potentially increasing compilation times
- Steeper learning curve due to more extensive API
- May introduce dependencies that are unnecessary for smaller projects
Code Comparison
WIL (Windows Implementation Library):
wil::unique_handle fileHandle;
THROW_IF_FAILED(OpenFile(L"example.txt", &fileHandle));
Abseil:
absl::Status status = OpenFile("example.txt", &file_handle);
if (!status.ok()) {
// Handle error
}
Summary
WIL is focused on Windows development, providing lightweight wrappers and utilities for Windows APIs. It's ideal for Windows-specific projects and integrates well with the Windows ecosystem.
Abseil offers a more comprehensive set of utilities and data structures, with cross-platform support. It's suitable for larger projects that require additional functionality beyond basic system interactions.
The choice between WIL and Abseil depends on the project's requirements, target platforms, and desired level of abstraction. WIL is more appropriate for Windows-centric development, while Abseil is better suited for cross-platform projects or those requiring advanced data structures and algorithms.
Super-project for modularized Boost
Pros of Boost
- Extensive library collection covering a wide range of functionalities
- Cross-platform support for multiple operating systems and compilers
- Large and active community with frequent updates and improvements
Cons of Boost
- Larger footprint and potential overhead for projects not using all features
- Steeper learning curve due to the breadth of the library
- Can be complex to integrate and manage dependencies in some projects
Code Comparison
WIL (Windows Implementation Library):
wil::unique_handle fileHandle;
THROW_IF_FAILED(wil::unique_handle::Create(
CreateFile(L"example.txt", GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr),
fileHandle));
Boost:
boost::filesystem::path filePath("example.txt");
boost::filesystem::ifstream file(filePath, std::ios::in | std::ios::binary);
if (!file)
throw std::runtime_error("Failed to open file");
Summary
WIL focuses on Windows-specific development, providing lightweight wrappers and utilities for common Windows APIs. Boost, on the other hand, offers a comprehensive set of libraries for various programming tasks across multiple platforms. While WIL excels in Windows-centric projects with its targeted approach, Boost provides broader functionality at the cost of increased complexity and resource usage.
An open-source C++ library developed and used at Facebook.
Pros of Folly
- More comprehensive library with a wider range of utilities and components
- Better support for modern C++ features and idioms
- Higher performance in many scenarios due to optimized implementations
Cons of Folly
- Larger codebase and potentially higher learning curve
- May introduce more dependencies and increase build times
- Less focused on Windows-specific scenarios compared to WIL
Code Comparison
WIL (Windows Implementation Library):
wil::unique_handle fileHandle;
THROW_IF_FAILED(wil::unique_handle::Create(
CreateFile(L"example.txt", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr),
fileHandle));
Folly:
folly::File file("example.txt", O_RDONLY);
auto fileHandle = file.fd();
if (fileHandle == -1) {
throw std::runtime_error("Failed to open file");
}
Summary
Folly offers a more extensive set of utilities and better support for modern C++ features, while WIL focuses on simplifying Windows development. Folly may provide higher performance but comes with a larger codebase and potential complexity. WIL is more tailored for Windows-specific scenarios and may be easier to integrate for Windows-centric projects.
GoogleTest - Google Testing and Mocking Framework
Pros of GoogleTest
- More comprehensive testing framework with support for various test types (unit, integration, etc.)
- Extensive documentation and community support
- Cross-platform compatibility (Windows, Linux, macOS)
Cons of GoogleTest
- Larger footprint and potential overhead for smaller projects
- Steeper learning curve for beginners compared to WIL's simpler approach
- May require more setup and configuration
Code Comparison
WIL (error handling):
HRESULT hr = S_OK;
RETURN_IF_FAILED(SomeFunction());
GoogleTest (test case):
TEST(TestSuiteName, TestName) {
EXPECT_EQ(SomeFunction(), 0);
ASSERT_TRUE(SomeCondition());
}
Summary
WIL focuses on Windows-specific error handling and resource management, while GoogleTest is a more comprehensive testing framework. WIL is lightweight and easier to integrate for Windows developers, but GoogleTest offers broader testing capabilities and cross-platform support. The choice between them depends on project requirements, target platform, and desired testing scope.
A modern formatting library
Pros of fmt
- Cross-platform compatibility (Windows, macOS, Linux)
- Faster compilation and runtime performance
- More extensive formatting options and type-safe interface
Cons of fmt
- Larger library size
- Requires C++11 or later
- Less integrated with Windows-specific features
Code Comparison
fmt:
#include <fmt/core.h>
std::string result = fmt::format("Hello, {}!", name);
fmt::print("The answer is {}.", 42);
WIL:
#include <wil/resource.h>
wil::unique_handle handle;
THROW_IF_FAILED(OpenHandle(&handle));
LOG_IF_FAILED(DoSomething());
Key Differences
- fmt focuses on string formatting and output across platforms
- WIL is tailored for Windows development with resource management and error handling
- fmt offers a more modern C++ interface
- WIL provides Windows-specific utilities and macros
Use Cases
- Choose fmt for cross-platform projects requiring advanced string formatting
- Opt for WIL in Windows-centric applications for better integration with Windows APIs and error handling
Community and Support
- fmt has a larger community and more frequent updates
- WIL benefits from Microsoft's backing and integration with Windows development ecosystem
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Windows Implementation Libraries (WIL)
The Windows Implementation Libraries (WIL) is a header-only C++ library created to make life easier for developers on Windows through readable type-safe C++ interfaces for common Windows coding patterns.
Some things that WIL includes to whet your appetite:
include/wil/resource.h
(documentation): Smart pointers and auto-releasing resource wrappers to let you manage Windows API HANDLEs, HWNDs, and other resources and resource handles with RAII semantics.include/wil/win32_helpers.h
(documentation): Wrappers for API functions that save you the work of manually specifying buffer sizes, calling a function twice to get the needed buffer size and then allocate and pass the right-size buffer, casting or converting between types, and so on.include/wil/registry.h
(documentation): Type-safe functions to read from, write to, and watch the registry. Also, registry watchers that can call a lambda function or a callback function you provide whenever a certain tree within the Windows registry changes.include/wil/result.h
(documentation): Preprocessor macros to help you check for errors from Windows API functions, in many of the myriad ways those errors are reported, and surface them as error codes or C++ exceptions in your code.include/wil/Tracelogging.h
: This file contains the convenience macros that enable developers define and log telemetry. These macros useTraceLogging API
to log data. This data can be viewed in tools such asWindows Performance Analyzer
.
WIL can be used by C++ code that uses C++ exceptions as well as code that uses returned error codes to report errors. All of WIL can be used from user-space Windows code, and some (such as the RAII resource wrappers) can even be used in kernel mode.
Documentation
This project is documented in its GitHub wiki. Feel free to contribute to it!
Consuming WIL
WIL follows the "live at head" philosophy, so you should feel free to consume WIL directly from the GitHub repo however you please: as a GIT submodule, symbolic link, download and copy files, etc. and update to the latest version at your own cadence. Alternatively, WIL is available using a few package managers, mentioned below. These packages will be updated periodically, likely to average around once or twice per month.
Consuming WIL via NuGet
WIL is available on nuget.org under the name Microsoft.Windows.ImplementationLibrary. This package includes the header files under the include directory as well as a .targets file.
Consuming WIL via vcpkg
WIL is also available using vcpkg under the name wil. Instructions for installing packages can be found in the vcpkg GitHub docs. In general, once vcpkg is set up on the system, you can run:
C:\vcpkg> vcpkg install wil:x86-windows
C:\vcpkg> vcpkg install wil:x64-windows
Note that even though WIL is a header-only library, you still need to install the package for all architectures/platforms you wish to use it with. Otherwise, WIL won't be added to the include path for the missing architectures/platforms. Execute vcpkg help triplet
for a list of available options.
Building/Testing
Prerequisites
To get started contributing to WIL, first make sure that you have:
- The latest version of Visual Studio or Build Tools for Visual Studio with the latest MSVC C++ build tools and Address Sanitizer components included.
- The most recent Windows SDK
- Nuget downloaded and added to
PATH
- (
winget install nuget
; see Install NuGet client tools)
- (
- vcpkg available on your system.
Follow their getting started guide to get set up.
You'll need to provide the path to vcpkg when initializing with CMake by passing
-DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake
. Note that if you use theinit.cmd
script (mentioned below), this path can be specified or auto-detected if you:- Manually specify the path to the root of your vcpkg clone via the
-p
or--vcpkg
argument, - Have the
VCPKG_ROOT
environment variable set to the root of your vcpkg clone. You can use thesetx
command to have this variable persist across shell sessions, - Have the path to the root of your vcpkg clone added to your
PATH
(i.e. the path tovcpkg.exe
), or - If your vcpkg clone is located at the root of the same drive as your WIL clone (e.g.
C:\vcpkg
if your WIL clone is on theC:
drive)
- Manually specify the path to the root of your vcpkg clone via the
If you are doing any non-trivial work, also be sure to have:
- A recent version of Clang
- (
winget install -i llvm.llvm
and selectAdd LLVM to the system path for all users
)
- (
Initial configuration
Once everything is installed (you'll need to restart Terminal if you updated PATH
and don't have this 2023 fix), open a VS native command window (e.g. x64 Native Tools Command Prompt for VS 2022
[not Developer Command Prompt for VS2022
]).
- If you are familiar with CMake you can get started building normally.
- Otherwise, or if you prefer to skip all of the boilerplate, you can use the
init.cmd
script in the scripts directory. For example:
You can executeC:\wil> scripts\init.cmd -c clang -g ninja -b debug
init.cmd --help
for a summary of available options. Thescripts/init_all.cmd
script will run theinit.cmd
script for all combinations of Clang/MSVC and Debug/RelWithDebInfo. Note that for either script, projects will only be generated for the architecture of the current VS command window.
To set up Visual Studio with IntelliSense, see below.
If you used the init.cmd
script, the corresponding build output directory should contain a compile_commands.json
file that describes the commands used to compile each input file.
Some editors such as Visual Studio Code can be configured to use this file to provide better auto-complete, tooltips, etc.
Visual Studio Code, in particular should auto-detect the presence of this file and prompt you to use it for better IntelliSense.
If you are not auto-prompted, this can be manually configured in the workspace's C/C++ properties under the property name compileCommands
.
Visual Studio setup
To generate a Visual Studio solution with IntelliSense:
C:\wil> scripts\init.cmd -c msvc -g msbuild
That will create a .sln
file in the corresponding build/
subdirectory (e.g. build/msvc64debug
).
You can open this solution in Visual Studio to develop and build, or you can invoke MSBuild directly.
Important! When using MSVC as the generator, the build type (
-b
argument toinit.cmd
) is mostly ignored by Visual Studio (since you can change the build type in the IDE), however this selection may still have an impact on project generation due to logic in the CMake files.
You can also get decent IntelliSense just by opening the repo directory in Visual Studio; VS should auto-detect CMake. You'll have to compile and run tests in a terminal window, though.
Inner loop
The scripts use a common directory pattern of build/$(compiler)$(arch)$(type)
for the build output root. E.g. build/clang64debug
when using Clang as the compiler, x64 as the architecture, and Debug as the build type. It is this directory where you will want to build from.
For example, if you initialized using the command above (scripts\init.cmd -c clang -g ninja -b debug
), you can build the tests like so:
C:\wil\build\clang64debug> ninja
Or, if you want to only build a single test (e.g. for improved compile times):
C:\wil\build\clang64debug> ninja witest.noexcept
The output is a number of test executables. If you used the initialization script(s) mentioned above, or if you followed the same directory naming convention of those scripts, you can use the runtests.cmd script, which will execute any test executables that have been built, erroring out - and preserving the exit code - if any test fails. Note that MSBuild will modify the output directory names, so this script is only compatible with using Ninja as the generator.
Build everything
If you are at the tail end of of a change, you can execute the following to get a wide range of coverage:
C:\wil> scripts\init_all.cmd
C:\wil> scripts\build_all.cmd
C:\wil> scripts\runtests.cmd
Note that this will only test for the architecture that corresponds to the command window you opened. You will want to
repeat this process for the other architecture (e.g. by using the x86 Native Tools Command Prompt for VS 2022
in addition to x64
).
Formatting
This project has adopted clang-format
as the tool for formatting our code.
Please note that the .clang-format
at the root of the repo is a copy from the internal Windows repo with few additions.
In general, please do not modify it.
If you find that a macro is causing bad formatting of code, you can add that macro to one of the corresponding arrays in the .clang-format
file (e.g. AttributeMacros
, etc.), format the code, and submit a PR.
NOTE: Different versions of
clang-format
may format the same code differently. In an attempt to maintain consistency between changes, we've standardized on using the version ofclang-format
that ships with the latest version of Visual Studio. If you have LLVM installed and added to yourPATH
, the version ofclang-format
that gets picked up by default may not be the one we expect. If you leverage the formatting scripts we have provided in thescripts
directory, these should automatically pick up the proper version provided you are using a Visual Studio command window.
Before submitting a PR to the WIL repo we ask that you first run clang-format
on your changes.
There is a CI check in place that will fail the build for your PR if you have not run clang-format
.
There are a few different ways to format your code:
1. Formatting with git clang-format
Important! Git integration with
clang-format
is only available through the LLVM distribution. You can install LLVM through their GibHub releases page, viawinget install llvm.llvm
, or through the package manager of your choice.
Important! The use of
git clang-format
additionally requires Python to be installed and available on yourPATH
.
The simplest way to format just your changes is to use clang-format
's git
integration.
You have the option to do this continuously as you make changes, or at the very end when you're ready to submit a PR.
To format code continuously as you make changes, you run git clang-format
after staging your changes.
For example:
C:\wil> git add *
C:\wil> git clang-format --style file
At this point, the formatted changes will be unstaged.
You can review them, stage them, and then commit.
Please note that this will use whichever version of clang-format
is configured to run with this command.
You can pass --binary <path>
to specify the path to clang-format.exe
you would like the command to use.
If you'd like to format changes at the end of development, you can run git clang-format
against a specific commit/label.
The simplest is to run against upstream/master
or origin/master
depending on whether or not you are developing in a fork.
Please note that you likely want to sync/merge with the master branch prior to doing this step.
You can leverage the format-changes.cmd
script we provide, which will use the version of clang-format
that ships with Visual Studio:
C:\wil> git fetch upstream
C:\wil> git merge upstream/master
C:\wil> scripts\format-changes.cmd upstream/master
2. Formatting with clang-format
Important! The path to
clang-format.exe
is not added toPATH
automatically, even when using a Visual Studio command window. The LLVM installer has the option to add itself to the system or userPATH
if you'd like. If you would like the path to the version ofclang-format
that ships with Visual Studio added to your path, you will need to do so manually. Otherwise, therun-clang-format.cmd
script mentioned below (or, equivalently, building theformat
target) will manually invoke theclang-format.exe
under your Visual Studio install path.
An alternative, and generally easier option, is to run clang-format
either on all source files or on all source files you've modified.
Note, however, that depending on how clang-format
is invoked, the version used may not be the one that ships with Visual Studio.
Some tools such as Visual Studio Code allow you to specify the path to the version of clang-format
that you wish to use when formatting code, however this is not always the case.
The run-clang-format.cmd
script we provide will ensure that the version of clang-format
used is the version that shipped with your Visual Studio install:
C:\wil> scripts\run-clang-format.cmd
Additionally, we've added a build target that will invoke this script, named format
:
C:\wil\build\clang64debug> ninja format
Please note that this all assumes that your Visual Studio installation is up to date. If it's out of date, code unrelated to your changes may get formatted unexpectedly. If that's the case, you may need to manually revert some modifications that are unrelated to your changes.
NOTE: Occasionally, Visual Studio will update without us knowing and the version installed for you may be newer than the version installed the last time we ran the format all script. If that's the case, please let us know so that we can re-format the code.
Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
Top Related Projects
Guidelines Support Library
Abseil Common Libraries (C++)
Super-project for modularized Boost
An open-source C++ library developed and used at Facebook.
GoogleTest - Google Testing and Mocking Framework
A modern formatting library
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot