需要提前安装 node-gyp
,
node-gyp
只要有对应版本
的 python 与 c++ 环境, 应该就没啥问题了.
"devDependencies": {
"@types/node": "^20.4.8",
"@types/ffi-napi": "^4.0.7",
"ffi-napi": "^4.0.3",
"tsx": "^3.12.7",
"typescript": "^5.0.2",
}
import * as ffi from 'ffi-napi';
// 读写 string , 好像可以替代 读写 int
let kernel32 = new ffi.Library('kernel32.dll', {
GetPrivateProfileStringA: ["int", ['string', 'string', 'string', "pointer", 'int', 'string']],
WritePrivateProfileStringA: ["int", ["string", "string", "string", "string"]],
GetPrivateProfileSectionNamesA: ['int', ['pointer', 'int', 'string']],
GetPrivateProfileSectionA: ['int', ['string', 'pointer', 'int', 'string']]
});
export function readString(filePath: string, sectionName: string, keyName: string, defaultValue: string = "") {
const MAX_BUFFER_SIZE = 1024;
const lpReturnedString = Buffer.alloc(MAX_BUFFER_SIZE);
const result = kernel32.GetPrivateProfileStringA(
sectionName, // 节名称
keyName, // 键名称
defaultValue, // 默认值(如果键不存在时返回的值)
lpReturnedString as any, // 接收字符串值的缓冲区
MAX_BUFFER_SIZE, // 缓冲区大小
filePath // INI 文件的路径
);
const returnedString = lpReturnedString.toString('utf8', 0, result);
return returnedString;
}
export function writeString(filePath: string, sectionName: string, keyName: string, value: string) {
let res = kernel32.WritePrivateProfileStringA(sectionName, keyName, value, filePath)
return res != 0;
}
export function removeKey(filePath: string, sectionName: string, keyName: string) {
let res = kernel32.WritePrivateProfileStringA(sectionName, keyName, null, filePath)
return res != 0;
}
export function removeSection(filePath: string, sectionName: string) {
let res = kernel32.WritePrivateProfileStringA(sectionName, null, null, filePath)
return res != 0;
}
export function readAllSectionNames(filePath: string) {
const MAX_BUFFER_SIZE = 32767;
const lpReturnedString = Buffer.alloc(MAX_BUFFER_SIZE);
const result = kernel32.GetPrivateProfileSectionNamesA(
lpReturnedString as any, // 接收节名称列表的缓冲区指针
MAX_BUFFER_SIZE, // 缓冲区大小
filePath // INI 文件的路径
);
const sectionNames = lpReturnedString.toString('utf8', 0, result).split('\0').filter(Boolean);
return sectionNames;
}
export function readKeyAndValue(filePath: string, sectionName: string) {
const MAX_BUFFER_SIZE = 32767;
const lpReturnedString = Buffer.alloc(MAX_BUFFER_SIZE);
const result = kernel32.GetPrivateProfileSectionA(
sectionName, // 节名称
lpReturnedString as any, // 接收键值对列表的缓冲区指针
MAX_BUFFER_SIZE, // 缓冲区大小
filePath // INI 文件的路径
);
// 从缓冲区读取键值对列表并进行解析
const keyValuePairs = lpReturnedString.toString('utf8', 0, result).split('\0').filter(Boolean);
let retMap = new Map<string, string>();
for (const item of keyValuePairs) {
let a = item.split('=');
retMap.set(a[0], a[1])
}
return retMap;
}
// 读取所有内容
export function readAllData(filePath: string) {
let ret = new Map<string, Map<string, string>>();
let sectionList = readAllSectionNames(filePath);
for (const sectionName of sectionList) {
let keyList = readKeyAndValue(filePath, sectionName)
let obj = new Map<string, string>();
for (const item of keyList) {
obj.set(item[0], item[1])
}
ret.set(sectionName, obj)
}
return ret;
}