.NET library “Vanara”: A simple and easy-to-use Windows API wrapper library

.NET library “Vanara”: A simple and easy-to-use Windows API wrapper library

A series of very simple and easy-to-use .NET libraries that provide excellent wrappers for the Windows API, almost eliminating the need to write tedious Windows API conversion functions.

Last updated 6/28/2021 10:53 PM
沙漠尽头的狼
6 min read
Category
.NET
Topic
C# Open Source Projects
Tags
.NET C# Windows API

Repository: https://github.com/dahall/Vanara

Translation: DesertEndWave (limited proficiency; please refer to the repository if possible)

A set of .NET libraries that are extremely easy to use and provide excellent encapsulation of the Windows API, almost eliminating the need to write tedious Windows API conversion functions.

This project contains various .NET assemblies that include P/Invoke functions, interfaces, enums, and structures from Windows libraries. Each assembly is closely related to one or a few libraries. For example, Shlwapi.dll contains all functions exported from Shlwapi.lib; Kernel32.dll contains everything from Kernel32.lib and kernelbase.lib.

All assemblies are available via NuGet and provide versions targeting .NET 2.0, 3.5, 4.0, 4.5, Core 3.0, Core 3.1, and .NET 5.0 (new in v3.2.20), with support for SourceLink. Where dependencies permit, .NET Standard 2.0, .NET Core 2.0, and 2.1 versions are also included for UWP and other .NET Core and Standard projects.

After thorough testing, a new version of this project is released every few weeks. New versions and release notes are cataloged in the Releases section, and all NuGet packages are published to nuget.org. Each GitHub push triggers an AppVeyor build. The owner thanks them for the free open-source account! The project build status is displayed at the beginning of the article. AppVeyor Source is used for building NuGet packages.

How to Use?

  1. Find the desired function in Microsoft documentation. Note which library or DLL the function belongs to.

  2. Check the table of supported libraries below to see if a Vanara library exists and contains the function (Windows API) you need. Clicking the assembly link will take you to a detailed view of that assembly's coverage. Find your function; if a matching implementation exists, it will appear on the right. You can also use GitHub's project search (top-left corner of the page) to search for functions, methods, or constants. Make sure to select "In this repository".

  3. Add the assembly to your project via NuGet.

  4. To use the function, you can:

      1. Directly call var bret = Vanara.PInvoke.Kernel32.GetComputerName(sb, ref sbSz);
      1. In C# 6.0 and later, use the static using directive and call it:
using static Vanara.PInvoke.Kernel32;

var bret = GetComputerName(sb, ref sbSz);
  1. In some cases, one of the supporting assemblies contains a corresponding helper/wrapper class, especially for Security, System Services, Forms, and Shell. Go to their library page (click the link in the section) to browse the classes included in each library.

Design Philosophy

  • All functions imported from a single DLL should be placed into a single assembly named after that DLL.
    • (e.g., the assembly Vanara.PInvoke.Gdi32.dll hosts all functions exported from gdi32.dll in the system directory, along with supporting enums, constants, and structures.)
  • Any structures, macros, or enums (non-functions) used by many libraries are placed into Vanara.Core or Vanara.PInvoke.Shared libraries.
    • (e.g., the macro HIWORD and the structure SIZE are both in Vanara.PInvoke.Shared; classes for simplifying interop calls and native memory management are in Vanara.Core.)
  • Within a project, all constructs are contained in a file named after the header file (*.h) where these structures are defined in the Windows API.
    • (e.g., in the Vanara.PInvoke.Kernel32 project directory, you'll find FileApi.cs, WinBase.cs, and WinNT.cs files corresponding to FileApi.h, WinBase.h, and WinNT.h respectively.)
  • If directly interpreting the structure or function would cause memory leaks or misuse, I've attempted to simplify its usage.
  • Where structures are always passed by reference and memory allocation cleanup is required, I've changed the structure to a class implementing IDisposable.
  • Whenever possible, all handles have been converted to SafeHandle derived tools named after the Windows API handle. If these handles require a function call to release/close/destroy, a derived SafeHANDLE exists that will execute that function upon disposal.
    • e.g., HTOKEN is defined. SafeHTOKEN calls CloseHandle on that handle to automatically release.
  • Whenever possible, all functions that allocate caller-freed memory use safe memory handles.
  • All PInvoke calls in the assembly are prefixed with Vanara.PInvoke.
  • If a structure is to be passed as a constant to a function, the in statement is used to wrap the structure, which passes the structure by reference without needing the ref keyword.
    • Windows API: BOOL MapDialogRect(HWND hDlg, LPRECT lprc)
    • Vanara: bool MapDialogRect(HWND hDlg, in RECT lpRect);
  • If there are classes or extensions that use PInvoke calls, they are placed in wrapper assemblies prefixed with Vanara, followed by the logical name of the functionality. Today these are Core, Security, SystemServices, Windows.Forms, and Windows.Shell.

Supported Libraries

Supporting Assemblies

Sample Code

There are numerous examples in the UnitTest folder and in the WinClassicSamplesCS project that recreates the Windows Samples in C# using Vanara.

Keep Exploring

Related Reading

More Articles