ZKEmkeeper SDK在Windows服务中OnAttTransactionEx事件不触发问题求助
问题排查与修复方案
核心问题1:SDK实例被垃圾回收
你的CZKEM objCZKEM是Connect_Net方法内的局部变量,方法执行完毕后该实例会被GC回收,直接导致后续设备事件无法被捕获。必须将CZKEM实例提升为类级别的成员变量,保证其生命周期与服务一致。
核心问题2:事件注册顺序错误
SDK要求先绑定事件回调,再调用RegEvent开启事件监听。你当前先调用RegEvent再绑定事件,顺序颠倒会导致事件触发逻辑失效。
次要问题:STA线程缺少消息循环
Windows服务中的STA线程需要消息循环才能处理COM组件的事件回调,你当前的while循环只是持续写日志,没有处理消息队列,会阻塞事件分发。
修复后的代码示例
1. 修改ZKemClient类,将CZKEM实例改为成员变量
public class ZKemClient { // 提升为类成员,避免被GC回收 private CZKEM _objCZKEM; private string _filepath; public ZKemClient(string filepath) { _filepath = filepath; _objCZKEM = new CZKEM(); } public bool Connect_Net(string IPAdd, int Port) { bool bResult = false; try { if (_objCZKEM.Connect_Net(IPAdd, Port)) { // 先注册事件,再调用RegEvent _objCZKEM.OnAttTransactionEx += zkemClient_OnAttTransactionEx; // RegEvent参数说明:1表示监听设备,32767是所有事件掩码 if (_objCZKEM.RegEvent(1, 32767)) { WriteToFile("事件监听已开启"); bResult = true; } else { WriteToFile("RegEvent调用失败"); } } else { WriteToFile("设备连接失败"); } } catch (Exception ex) { WriteToFile("Connect_Net() 异常->" + ex.Message); } return bResult; } private void zkemClient_OnAttTransactionEx(string EnrollNumber, int IsInValid, int AttState, int VerifyMethod, int Year, int Month, int Day, int Hour, int Minute, int Second, int WorkCode) { // 处理考勤事件逻辑 WriteToFile($"收到考勤事件:卡号={EnrollNumber}, 时间={Year}-{Month}-{Day} {Hour}:{Minute}:{Second}"); } private void WriteToFile(string content) { // 你的日志实现 File.AppendAllText(_filepath, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {content}{Environment.NewLine}"); } }
2. 修改WorkedThread的消息循环
替换原来的死循环,使用Application.Run()启动STA线程的消息循环(需引用System.Windows.Forms):
private void WorkedThread() { WriteToFile("Worker Thread Started."); ZKemClient objZkeeper = new ZKemClient(filepath); this.isDeviceConnected = objZkeeper.Connect_Net("19x.x.x.24x", 4370); if (this.isDeviceConnected) { WriteToFile("Device connected."); // 启动STA线程的消息循环,处理COM事件 Application.Run(); } else { WriteToFile("Failed to connect to Device."); } }
额外检查点
- 确保服务运行账号有足够权限访问设备网络
- 验证设备端是否开启事件推送功能(部分设备需在Web后台配置)
- 检查SDK版本与设备固件版本是否兼容
- 确认防火墙允许服务与设备的4370端口通信
内容的提问来源于stack exchange,提问作者Anup W
相关产品推荐
相关产品推荐

