初始化 npm init -y
添加index.js
const ffi = require('ffi-napi');
const ref = require('ref-napi');
const Struct = require('ref-struct-napi');
const ArrayType = require('ref-array-napi');
// 定义C语言中的类型
const charPtr = ref.types.CString; // LPSTR 是指向以 null 结尾的字符串的指针
const ulong = ref.types.ulong;
const int32 = ref.types.int32;
const HANDLE = ref.refType(ref.types.void); // 定义 HANDLE 类型
// 将 DEVHANDLE 定义为 HANDLE
const DEVHANDLE = HANDLE;
// 定义 VERSION 结构体
const VERSION = Struct({
major: ref.types.byte,
minor: ref.types.byte
});
// 定义 DEVINFO 结构体
const DEVINFO = Struct({
Version: VERSION,
Manufacturer: ArrayType(ref.types.char, 64),
Issuer: ArrayType(ref.types.char, 64),
Label: ArrayType(ref.types.char, 32),
SerialNumber: ArrayType(ref.types.char, 32),
HWVersion: VERSION,
FirmwareVersion: VERSION,
AlgSymCap: ref.types.uint32,
AlgAsymCap: ref.types.uint32,
AlgHashCap: ref.types.uint32,
DevAuthAlgId: ref.types.uint32,
TotalSpace: ref.types.uint32,
FreeSpace: ref.types.uint32,
MaxECCBufferSize: ref.types.uint32,
MaxBufferSize: ref.types.uint32,
Reserved: ArrayType(ref.types.byte, 64)
});
// 创建 DEVINFO 实例
const devInfo = new DEVINFO();
// 加载DLL
const exampleLib = ffi.Library('fteps3000gmg.dll', { //连接dll动态库及里面的函数方法
'SKF_WaitForDevEvent': [ulong, [charPtr, ref.refType(ulong), ref.refType(ulong)]],
'SKF_ConnectDev': [int32, [charPtr, ref.refType(DEVHANDLE)]],
'SKF_GetDevInfo': ['int', [DEVHANDLE, ref.refType(DEVINFO)]]
});
// 准备参数
const devName = Buffer.alloc(1024).fill(0);
const devNameLen = ref.alloc(ulong, devName.length);
const event = ref.alloc(ulong, 0);
const result = exampleLib.SKF_WaitForDevEvent(devName, devNameLen, event);
let eventTypes = ref.deref(event, ulong);
// 输出事件类型
console.log(`Event type: ${eventTypes}`);
if(eventTypes == 1) {
if (result === 0) {
// 调用DLL中的函数
const phDev = ref.alloc(DEVHANDLE);
const connectResult = exampleLib.SKF_ConnectDev('ePass3000GM-G VCR', phDev);
if (connectResult === 0) { // 假设 0 表示成功
console.log(`Connected to device successfully. Handle: ${phDev.deref()}`);
const getInfoResult = exampleLib.SKF_GetDevInfo(phDev.deref(), devInfo.ref());
if (getInfoResult === 0) {
// 访问DEVINFO结构体的各个字段
console.log(`Version: Major=${devInfo.Version.major}, Minor=${devInfo.Version.minor}`);
console.log(`Manufacturer: ${Buffer.from(devInfo.Manufacturer.buffer, 0, devInfo.Manufacturer.length).toString('utf8').replace(/\0/g, '')}`);
console.log(`Issuer: ${Buffer.from(devInfo.Issuer.buffer, 0, devInfo.Issuer.length).toString('utf8').replace(/\0/g, '')}`);
console.log(`Label: ${Buffer.from(devInfo.Label.buffer, 0, devInfo.Label.length).toString('utf8').replace(/\0/g, '')}`);
console.log(`SerialNumber: ${Buffer.from(devInfo.SerialNumber.buffer, 0, devInfo.SerialNumber.length).toString('utf8').replace(/\0/g, '')}`);
let serialNumberStr = Buffer.from(devInfo.SerialNumber.buffer, 0, devInfo.SerialNumber.length).toString('utf8').replace(/\0/g, '')
let serialNumberHexChars = '';
for (let i = 0; i < serialNumberStr.length; i++) {
let charCode = serialNumberStr.charCodeAt(i);
let byte = charCode & 0xFF;
let hexCharCode = byte.toString(16).padStart(2, '0'); // 确保每个字符都是两位数
serialNumberHexChars += hexCharCode + ''; // 在每个字符后添加一个空格以增加可读性
}
console.log(`serialNumberHexChars: ${serialNumberHexChars}`);
} else {
console.error(`Failed to retrieve device info. Error code: ${getInfoResult}`);
}
} else {
console.error(`U盘已拔出,错误码为: ${connectResult}`);
}
}else {
console.log('No device name was received.');
}
}else if(eventTypes == 2){
console.log('U盘已拔出');
}else {
console.log('请插入u盘');
}
需要用的库
根据nodejs的命令获取到的一些数据