-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Description
Current ffi-rs version:^1.3.1
const { define, DataType, open,arrayConstructor, FFITypeTag } = require('ffi-rs');
// 1. 定义常量
const TH32CS_SNAPPROCESS = 0x00000002;
const INVALID_HANDLE_VALUE = -1;
// 2. 打开 kernel32.dll 并定义函数
// ffi-rs 使用对象映射的方式定义参数和返回值
open({ library: 'kernel32', path: 'kernel32.dll' });
const PROCESSENTRY32 = {
dwSize: DataType.U32,
cntUsage: DataType.U32,
th32ProcessID: DataType.U32,
// 将 External 改为 I64
th32DefaultHeapID: DataType.I64,
th32ModuleID: DataType.U32,
cntThreads: DataType.U32,
th32ParentProcessID: DataType.U32,
pcPriClassBase: DataType.I32,
dwFlags: DataType.U32,
szExeFile: arrayConstructor({
type: DataType.U8Array, // 使用 U8Array 对应 ANSI 字符
length: 260,
ffiTypeTag: FFITypeTag.StackArray
})
};
const kernel32 = define({
CreateToolhelp32Snapshot: {
library: 'kernel32',
retType: DataType.I64, // 句柄在 64 位系统上通常视为 i64
paramsType: [DataType.U32, DataType.U32],
},
Process32First: {
library: 'kernel32',
retType: DataType.Boolean,
paramsType: [DataType.I64, PROCESSENTRY32],
},
Process32Next: {
library: 'kernel32',
retType: DataType.Boolean,
paramsType: [DataType.I64, PROCESSENTRY32],
},
CloseHandle: {
library: 'kernel32',
retType: DataType.Boolean,
paramsType: [DataType.I64],
}
});
// 3. 调用函数获取快照句柄
// 第一个参数是快照类型,第二个参数是进程 ID(0 表示当前系统所有进程)
const hSnapshot = kernel32.CreateToolhelp32Snapshot([TH32CS_SNAPPROCESS, 0]);
// 初始化结构体对象
const entry = {
dwSize: 304, // x64 下 ANSI 结构体的正确尺寸
cntUsage: 0,
th32ProcessID: 0,
padding: 0, // 必须传值,不能省略
th32DefaultHeapID: 0, // I64 必须使用 BigInt
th32ModuleID: 0,
cntThreads: 0,
th32ParentProcessID: 0,
pcPriClassBase: 0,
dwFlags: 0,
szExeFile: Buffer.alloc(260)
};
if (kernel32.Process32First([hSnapshot, entry])) {
do {
console.log(entry.szExeFile); //问题:这里恒为空
// entry.szExeFile 现在是一个 Buffer,可以直接转换
// const name = entry.szExeFile.toString('utf-8').replace(/\0/g, '');
// if (name) {
// console.log(`PID: ${entry.th32ProcessID}\t Name: ${name}`);
// }
} while (kernel32.Process32Next([hSnapshot, entry]));
}
if (hSnapshot === BigInt(INVALID_HANDLE_VALUE)) {
console.error('无法创建进程快照');
return;
}
console.log(`成功获取快照句柄: ${hSnapshot}`);
// 4. 操作完成后必须关闭句柄防止内存泄漏
const closed = kernel32.CloseHandle([hSnapshot]);
console.log(`句柄关闭状态: ${closed}`);问题描述
在 Windows x64 环境下使用 ffi-rs 调用 CreateToolhelp32Snapshot 和 Process32First/Next 时,遇到以下问题:
数据截断/偏移:获取到的进程名(szExeFile)为空字符串或乱码。
环境信息
操作系统: Windows 10/11 x64
库版本: ffi-rs
Node.js: v16+
架构: x64(此架构下的内存对齐规则是问题的根本原因)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels