20.4.1 • Published 1 year ago

win32-api v20.4.1

Weekly downloads
84
License
MIT
Repository
github
Last release
1 year ago

win32-api

FFI Definitions of Windows win32 api for node-ffi-napi

GitHub tag License npm.io Available platform ci Build status codecov Conventional Commits lerna

Migrate to v13

See migrate13

Initialization

npm run bootstrap

Packages

PackageVersion
win32-apimain-svg
win32-defdef-svg

What can I do with this?

Calling win32 native functions come from user32.dll, kernel32.dll, comctl32.dll by Node.js via node-ffi-napi

Installing

npm install win32-api

Usage

DLL Wrapper

import { 
  user32FindWindowEx, 
  winspoolGetDefaultPrinter,
} from 'win32-api/fun'

// Retrieves the printer name of the default printer for the current user on the local computer
const printerName = await winspoolGetDefaultPrinter()

const child = spawn('notepad.exe')
const hWnd = await user32FindWindowEx(0, 0, 'Notepad', null)

Find window and set window title

// **Find calc's hWnd, need running a calculator program manually at first**

/**
 * Exposed modules:
 * Comctl32: Comctl32 from lib/comctl32/api
 * Kernel32: kernel32 from lib/kernel32/api
 * User32: user32 from lib/user32/api
 */
import { Kernel32, User32 } from 'win32-api/promise'
import ref from 'ref-napi'

const knl32 = Kernel32.load()
const user32 = User32.load()

// const user32 = load(['FindWindowExW'])  // load only one api defined in lib/{dll}/api from user32.dll

const title = 'Calculator\0'    // null-terminated string
// const title = '计算器\0'    // null-terminated string 字符串必须以\0即null结尾!

const lpszWindow = Buffer.from(title, 'ucs2')
const hWnd = await user32.FindWindowExW(0, 0, null, lpszWindow)

assert((typeof hWnd === 'string' && hWnd.length > 0) || hWnd > 0)
console.log('buf: ', hWnd)

// Change title of the Calculator
const res = await user32.SetWindowTextW(hWnd, Buffer.from('Node-Calculator\0', 'ucs2'))
if ( ! res) {
  console.log('SetWindowTextW failed')
}
else {
  console.log('window title changed')
}

Ref

import ref from 'ref-napi'

// so we can all agree that a buffer with the int value written
// to it could be represented as an "int *"
const buf  = Buffer.alloc(4)
buf.writeInt32LE(12345, 0)

const hex = ref.hexAddress(buf)
console.log(typeof hex)
console.log(hex)  // ← '7FA89D006FD8'

buf.type = ref.types.int  // @ts-ignore

// now we can dereference to get the "meaningful" value
console.log(ref.deref(buf))  // ← 12345
// use of types and windef:
import ref from 'ref-napi'
import { DModel as M } from 'win32-api'
import { Kernel32, User32 } from 'win32-api/promise'

const knl32 = Kernel32.load()
const user32 = User32.load()

const lpszClass = Buffer.from('guard64\0', 'ucs2')
const hInstanceBuffer = ref.alloc(W.HANDLE_PVOID)
const hInstanceAddr = ref.address(hInstanceBuffer)

await knl32.GetModuleHandleExW(0, lpszClass, hInstanceAddr)
// <Buffer@0x00000094D3968EC0 00 00 a4 60 ff 7f 00 00, type: { indirection: 2, name: 'uint64*' }>
console.log(hInstanceBuffer)
console.log(hInstanceBuffer.readInt32LE(0))     // -> 1621360640           (60A40000)
console.log(hInstanceBuffer.readBigUInt64LE())  // -> 140734814748672n (7FFF60A40000)

Struct

// struct usage with ref-struct
import { retrieveStructFromPtrAddress, StructFactory } from 'win32-api'
import {
  DModel as M,
  DTypes as W,
  DStruct as DS,
} from 'win32-api'

// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspx
const point = StructFactory<M.POINT>(DS.POINT)
point.x = 100
point.y = 200
console.log(point)

Struct

import { StructFactory } from 'win32-api'
import {
  DModel as M,
  DTypes as W,
  DStruct as DS,
} from 'win32-api'


// https://docs.microsoft.com/zh-cn/windows/win32/api/wingdi/ns-wingdi-display_devicew 
const dd: M.DISPLAY_DEVICEW = StructFactory(DS.DISPLAY_DEVICEW)
dd.cb = dd.ref().byteLength
console.log(dd)
// https://github.com/waitingsong/node-win32-api/blob/main/packages/win32-api/test/user32/51.user32.EnumDisplayDevicesW.test.ts

Async Find window and set window title

// **Find calc's hWnd, need running a calculator program manually at first**
import * as ref from 'ref-napi'

import {
  DModel as M,
  DTypes as W,
  DStruct as DS,
} from 'win32-api'
import { Kernel32, User32 } from 'win32-api/promise'


const knl32 = Kernel32.load()
const user32 = User32.load()

const lpszClass = Buffer.from('CalcFrame\0', 'ucs2')
// win10
const calcLpszWindow = Buffer.from('Calculator\0', 'ucs2')
// for win7/8
const calcLpszClass = Buffer.from('CalcFrame\0', 'ucs2')

const child = spawn('calc.exe')
const hWnd = await user32.FindWindowExW(0, 0, null, calcLpszWindow) // win10
const hWnd = await user32.FindWindowExW(0, 0, calcLpszClass , null) // win7/8
assert((typeof hWnd === 'string' && hWnd.length > 0) || hWnd > 0, 'found no calc window')

const title = 'Node-Calculator'
const len = title.length

const ret = await user32.SetWindowTextW(hWnd, Buffer.from(title + '\0', 'ucs2'))
assert(ret, 'SetWindowTextW() failed')

const buf = Buffer.alloc(len * 2)
await user32.GetWindowTextW(hWnd, buf, len + 1)
const str = buf.toString('ucs2').replace(/\0+$/, '')
assert(str === title.trim(), `title should be changed to "${title}", bug got "${str}"`)

child.kill() // seems not work under win10

Demo

Dependencies Troubleshooting

Compile successfully with

  • Node.js v18, Python v3.9 and VS2019, VS2022
  • Node.js v16, Python v3.9 and VS2019, VS2022
  • Node.js v14, Python v3.7 and VS2019

If installation of node-gyp fails: Check out node-gyp and node-gyp-on-windows, windows-build-tools

Relevant

License

MIT

Languages

20.3.0

1 year ago

20.4.1

1 year ago

20.4.0

1 year ago

20.2.0

1 year ago

19.8.3

2 years ago

19.8.2

2 years ago

20.0.0

2 years ago

20.1.0

2 years ago

19.0.0

2 years ago

10.0.0

2 years ago

13.7.0

2 years ago

13.3.0

2 years ago

14.1.0

2 years ago

19.4.0

2 years ago

18.2.0

2 years ago

19.8.1

2 years ago

19.8.0

2 years ago

13.10.0

2 years ago

12.0.0

2 years ago

13.14.0

2 years ago

19.3.0

2 years ago

15.0.0

2 years ago

13.8.0

2 years ago

13.4.0

2 years ago

13.0.0

2 years ago

19.7.0

2 years ago

18.1.0

2 years ago

13.11.0

2 years ago

17.0.0

2 years ago

13.15.0

2 years ago

11.1.1

2 years ago

11.1.0

2 years ago

19.2.1

2 years ago

19.2.0

2 years ago

15.1.0

2 years ago

13.9.0

2 years ago

13.5.0

2 years ago

18.4.0

2 years ago

19.2.2

2 years ago

13.1.0

2 years ago

19.6.0

2 years ago

18.0.0

2 years ago

13.12.0

2 years ago

17.1.1

2 years ago

17.1.0

2 years ago

11.0.2

2 years ago

11.0.3

2 years ago

11.0.0

2 years ago

11.0.1

2 years ago

19.1.0

2 years ago

13.6.0

2 years ago

13.2.0

2 years ago

14.0.0

2 years ago

13.2.1

2 years ago

19.5.0

2 years ago

18.3.0

2 years ago

17.2.1

2 years ago

17.2.0

2 years ago

13.13.0

2 years ago

16.0.1

2 years ago

16.0.0

2 years ago

9.6.0

4 years ago

9.5.0

4 years ago

9.4.0

4 years ago

9.3.0

4 years ago

9.2.0

4 years ago

9.1.0

4 years ago

9.0.0

4 years ago

7.1.0

4 years ago

8.0.0

4 years ago

7.0.2

4 years ago

7.0.1

4 years ago

7.0.0

4 years ago

6.2.0

5 years ago

6.1.0

5 years ago

6.0.0

5 years ago

5.2.0

5 years ago

5.1.0

5 years ago

5.0.1

5 years ago

5.0.0

5 years ago

3.10.0

5 years ago

4.2.0

5 years ago

3.9.0

5 years ago

4.1.0

5 years ago

3.8.0

5 years ago

3.7.1

5 years ago

4.0.2

5 years ago

4.0.1

5 years ago

3.7.0

5 years ago

4.0.0

5 years ago

3.6.0

6 years ago

3.5.1

6 years ago

3.4.0

6 years ago

3.3.0

6 years ago

3.2.0

6 years ago

3.1.0

6 years ago

3.0.2

6 years ago

3.0.1

6 years ago

3.0.0

6 years ago

1.12.0

6 years ago

2.0.0

6 years ago

1.11.2

6 years ago

1.11.1

6 years ago

1.11.0

6 years ago

1.10.1

6 years ago

1.10.0

6 years ago

1.9.1

6 years ago

1.9.0

6 years ago

1.8.1

6 years ago

1.8.0

6 years ago

1.7.1

7 years ago

1.7.0

7 years ago

1.6.2

7 years ago

1.6.1

7 years ago

1.6.0

7 years ago

1.5.2

7 years ago

1.5.1

7 years ago

1.5.0

7 years ago

1.4.4

7 years ago

1.4.3

7 years ago

1.4.1

7 years ago

1.4.0

7 years ago

1.3.3

7 years ago

1.3.2

7 years ago

1.3.1

7 years ago

1.3.0

7 years ago

1.2.0

7 years ago

1.1.1

7 years ago

1.1.0

7 years ago

1.0.0

7 years ago