Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

@tigerconnect/win32-api

Package Overview
Dependencies
Maintainers
5
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tigerconnect/win32-api

FFI definitions of windows win32 api for node-ffi


Version published
Maintainers
5
Created
Source

Fork of waitingsong/node-win32-api. Changes:

  • Replace ref-napi and @types/ref-napi with @tigerconnect/ref-napi for node v16 support, due to stacktraces in node v14 - v16 with ref-napi
  • Use @tigerconnect/ffi-napi fork instead of ffi-napi for the same reason
  • Use @tigerconnect/ref-union-di fork instead of ref-union-di to fix some CommonJS problems
  • Pin @types/ref-struct-di to 1.1.0 since 1.1.6 doesn't seem to work well
  • Remove OS requirement from win32-api package.json so we can still get access to types and APIs for test mocks
  • Require node 14.16.0 or higher
  • Upgrade eslint config and fix lint errors

win32-api

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

GitHub tag License Available platform Build status Coverage Status Conventional Commits lerna

Initialization

npm run repo:init

Packages

PackageVersionDependenciesDevDependencies
win32-apimain-svgmain-d-svgmain-dd-svg
win32-defdef-svgdef-d-svgdef-dd-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 @tigerconnect/win32-api

Usage

Find window and set window title

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

/**
 * exposed modules:
 * C, Comctl32 for Comctl32 from lib/comctl32/api
 * K, Kernel32 for kernel32 from lib/kernel32/api
 * U, User32 for user32 from lib/user32/api
 */
import { K, U } from '@tigerconnect/win32-api'
import * as ref from '@tigerconnect/ref-napi'

const knl32 = K.load()
const user32 = U.load()  // load all apis defined in lib/{dll}/api from user32.dll
// const user32 = U.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 = user32.FindWindowExW(0, 0, null, lpszWindow)

if (typeof hWnd === 'number' && hWnd > 0
  || typeof hWnd === 'bigint' && hWnd > 0
  || typeof hWnd === 'string' && hWnd.length > 0
) {
  console.log('buf: ', hWnd)

  // Change title of the Calculator
  const res = user32.SetWindowTextW(hWnd, Buffer.from('Node-Calculator\0', 'ucs2'))

  if ( ! res) {
    console.log('SetWindowTextW failed')
  }
  else {
    console.log('window title changed')
  }
}

Ref

import { U } from '@tigerconnect/win32-api'
import * as ref from '@tigerconnect/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 * as ref from '@tigerconnect/ref-napi'
import { K, DTypes as W } from '@tigerconnect/win32-api'


const knl32 = K.load()

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

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 * as Struct from 'ref-struct'
import { DModel as M, DStruct as DS } from '@tigerconnect/win32-api'

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

// struct usage with ref-struct-di
import * as ref from '@tigerconnect/ref-napi'
import * as StructDi from 'ref-struct-di'
import { DModel as M, DStruct as DS } from '@tigerconnect/win32-api'

const Struct = StructDi(ref)
const point: M.POINT_Struct = new Struct(DS.POINT)()
point.x = 100
point.y = 200
console.log(point)

StructExt

// struct usage with ref-struct
import * as Struct from 'ref-struct-napi'
import {
  DModel as M,
  DStructExt,
} from '@tigerconnect/win32-api'


// https://docs.microsoft.com/zh-cn/windows/win32/api/wingdi/ns-wingdi-display_devicew 
const dd: M.DISPLAY_DEVICEW_Struct = new Struct(DStructExt.DISPLAY_DEVICEW)()
dd.cb = dd.ref().byteLength
console.log(dd)
/**
Detail in:
https://github.com/waitingsong/node-win32-api/blob/master/packages/win32-api/src/data-struct-ext/wingdi.h.ts
https://github.com/waitingsong/node-win32-api/blob/master/packages/win32-api/test/user32/60_EnumDisplayDevicesW.test.ts
*/

Async Find window and set window title

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

import { U } from '@tigerconnect/win32-api'
import * as ref from '@tigerconnect/ref-napi'


const u32 = U.load(['FindWindowExW', 'SetWindowTextW'])
const lpszClass = Buffer.from('CalcFrame\0', 'ucs2')

u32.FindWindowExW.async(0, 0, lpszClass, null, (err, hWnd) => {
  if (err) {
    throw err
  }

  if (typeof hWnd === 'number' && hWnd > 0
    || typeof hWnd === 'bigint' && hWnd > 0
    || typeof hWnd === 'string' && hWnd.length > 0
  ) {
    const title = 'Node-Calculator'
    // Change title of the Calculator
    u32.SetWindowTextW.async(hWnd, Buffer.from(title + '\0', 'ucs2'), err2 => {
      if (err2) {
        throw err2
      }

      const buf = Buffer.alloc(title.length * 2)
      u32.GetWindowTextW.async(hWnd, buf, buf.byteLength, err3 => {
        if (err3) {
          throw err3
        }

        const str = buf.toString('ucs2').replace(/\0+$/, '')
        if (str !== title) {
          throw new Error(`title should be changed to ${title}, bug got ${str}`)
        }
      })
    })
  }
  else {
    throw new Error('FindWindowExW() failed')
  }
})

Demo

Dependencies Troubleshooting

Compile successfully with

  • Node.js v12, Python v3.7 and VS2017
  • Node.js v10, Python v2.7 and VS2017

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

Relevant

License

MIT

Languages

Keywords

FAQs

Package last updated on 09 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc