@bun-win32/dismapi
v2.0.1
Published
Zero-dependency, zero-overhead Win32 DISM API bindings for Bun (FFI) on Windows.
Maintainers
Readme
@bun-win32/dismapi
Zero-dependency, zero-overhead Win32 DISM API bindings for Bun on Windows.
Overview
@bun-win32/dismapi exposes the dismapi.dll exports using Bun's FFI. It provides a single class, Dismapi, which lazily binds native symbols on first use. You can optionally preload a subset or all symbols up-front via Preload().
The Deployment Image Servicing and Management (DISM) API is the supported, in-process way to install/uninstall/configure/update Windows features, packages, drivers, and capabilities in an online or offline Windows image (.wim/.vhd/.vhdx) — the same engine DISM.exe drives, with no process spawn.
The bindings are strongly typed for a smooth DX in TypeScript.
Features
- Bun-first ergonomics on Windows 10/11.
- Direct FFI to
dismapi.dll(image servicing: sessions, features, packages, drivers, capabilities, health, mount). - In-source docs in
structs/Dismapi.tswith links to Microsoft Docs. - Lazy binding on first call; optional eager preload (
Dismapi.Preload()). - No wrapper overhead; calls map 1:1 to native APIs.
- Strongly-typed Win32 aliases (see
types/Dismapi.ts).
Requirements
- Bun runtime
- Windows 10 or later
- An elevated process (the DISM API returns
ERROR_ELEVATION_REQUIREDotherwise)
Installation
bun add @bun-win32/dismapiQuick Start
import Dismapi, { DISM_ONLINE_IMAGE, DismLogLevel, DismPackageIdentifier } from '@bun-win32/dismapi';
if (Dismapi.DismInitialize(DismLogLevel.DismLogErrorsWarnings, null, null) === 0) {
const sess = Buffer.alloc(4); // DismSession is a UINT
const online = Buffer.from(DISM_ONLINE_IMAGE + '\0', 'utf16le');
if (Dismapi.DismOpenSession(online.ptr, null, null, sess.ptr) === 0) {
const session = sess.readUInt32LE(0);
const arr = Buffer.alloc(8); // receives a DISM-allocated array pointer
const count = Buffer.alloc(4);
Dismapi.DismGetFeatures(session, null, DismPackageIdentifier.DismPackageNone, arr.ptr, count.ptr);
console.log('optional features:', count.readUInt32LE(0));
Dismapi.DismCloseSession(session);
}
Dismapi.DismShutdown(); // always pair with DismInitialize
}[!NOTE] AI agents: see
AI.mdfor the package binding contract and source-navigation guidance. It explains how to use the package without scanning the entire implementation.
Examples
Run the included examples (run elevated for full output):
bun run example/servicing-inventory.ts
bun run example/image-health-report.tsNotes
- Either rely on lazy binding or call
Dismapi.Preload(). DismSessionis aUINT(number), not a handle — read it from a 4-byte buffer afterDismOpenSession.DismGet*functions return a DISM-allocated array via aT**out-pointer plus aUINTcount; you read the count from your own buffer, then walk the returned pointer and must free it withDismDelete.- Long-running functions accept an optional
CancelEvent(eventHANDLE,0nfor none),Progress(DISM_PROGRESS_CALLBACK,nullfor none), andUserData(nullfor none). - Always pair
DismInitialize/DismShutdownandDismOpenSession/DismCloseSession. - Six
dismapi.dllexports (DismAddLanguage,DismAddProvisionedAppxPackage,DismGetPackageInfoEx,DismGetProvisionedAppxPackages,DismRemoveLanguage,DismRemoveProvisionedAppxPackage) are undocumented and intentionally not bound. - Windows only. Bun runtime required.
- SAL types & naming: nullability is in the type —
Optional<T>(formally optional, SAL_*opt_) andNullable<T>(plain[in]/[out]the docs say can be NULL), the null sentinel derived fromT(nullfor pointersLP*/P*,0nfor handles/by-value addresses); direction is in the parameter name —_out(_Out_),_in_out(_Inout_),_In_bare. SeeAI.mdand the repoAGENTS.md.
