最近在倒腾中控指纹仪,用的是官方提供的sdk 地址
在使用过程中需要对进出记录进行实时监控,开发包也有这个功能,不使用多线程winform下连接一台指纹仪正常,可以反馈事件,代码如下
1 namespace AttLogs 2 { 3 public partial class AttLogsMain : Form 4 { 5 public AttLogsMain() 6 { 7 InitializeComponent(); 8 } 9 10 //Create Standalone SDK class dynamicly. 11 public zkemkeeper.CZKEMClass axCZKEM1 = new zkemkeeper.CZKEMClass(); 12 13 #region 连接指纹仪 14 private void btnConnect_Click(object sender, EventArgs e) 15 { 16 if (txtIP.Text.Trim() == "" || txtPort.Text.Trim() == "") 17 { 18 MessageBox.Show("IP and Port cannot be null", "Error"); 19 return; 20 } 21 int idwErrorCode = 0; 22 23 Cursor = Cursors.WaitCursor; 24 25 bIsConnected = axCZKEM1.Connect_Net(txtIP.Text, Convert.ToInt32(txtPort.Text)); 26 if (bIsConnected == true) 27 { 28 btnConnect.Text = "DisConnect"; 29 btnConnect.Refresh(); 30 lblState.Text = "Current State:Connected"; 31 iMachineNumber = 1; 32 if (axCZKEM1.RegEvent(iMachineNumber, 65535))//打开指纹仪实时事件功能 33 { 34 //注册事件 35 this.axCZKEM1.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx); 36 this.axCZKEM1.OnFingerFeature += new zkemkeeper._IZKEMEvents_OnFingerFeatureEventHandler(axCZKEM1_OnFingerFeature); 37 } 38 } 39 else 40 { 41 axCZKEM1.GetLastError(ref idwErrorCode); 42 MessageBox.Show("Unable to connect the device,ErrorCode=" + idwErrorCode.ToString(), "Error"); 43 } 44 Cursor = Cursors.Default; 45 46 Cursor = Cursors.Default; 47 } 48 #endregion 49 50 #region 事件处理 51 52 private void axCZKEM1_OnAttTransactionEx(string sEnrollNumber, int iIsInValid, int iAttState, int iVerifyMethod, int iYear, int iMonth, int iDay, int iHour, int iMinute, int iSecond, int iWorkCode) 53 { 54 lbRTShow.Items.Add("RTEvent OnAttTrasactionEx Has been Triggered,Verified OK"); 55 lbRTShow.Items.Add("...用户ID:" + sEnrollNumber); 56 lbRTShow.Items.Add("...验证方式:" + iIsInValid.ToString()); 57 lbRTShow.Items.Add("...attState:" + iAttState.ToString()); 58 lbRTShow.Items.Add("...VerifyMethod:" + iVerifyMethod.ToString()); 59 lbRTShow.Items.Add("...工号:" + iWorkCode.ToString());//the difference between the event OnAttTransaction and OnAttTransactionEx 60 lbRTShow.Items.Add("...时间:" + iYear.ToString() + "-" + iMonth.ToString() + "-" + iDay.ToString() + " " + iHour.ToString() + ":" + iMinute.ToString() + ":" + iSecond.ToString()); 61 } 62 #endregion 63 } 64 }
但如果连接多台设备就必须用多个线程(如使用单线程一台指纹仪连接有问题就会整个卡死),一个线程对应一个指纹仪,但线程执行完了就回收了,无法响应事件或用while(true) sleep(1000)阻止回收也不行
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Threading; 5 using zkemkeeper; 6 7 namespace ConsoleMThreads 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Thread thread = new Thread(new ThreadA().test); 14 thread.Start(); 15 Console.ReadKey(); 16 } 17 } 18 19 20 public class ThreadA 21 { 22 public zkemkeeper.CZKEMClass sdk = new CZKEMClass();//create Standalone SDK class dynamicly 23 24 public void test() 25 { 26 bIsConnected = axCZKEM1.Connect_Net("192.168.1.1", 4370); 27 if (bIsConnected == true) 28 { 29 iMachineNumber = 1; 30 if (axCZKEM1.RegEvent(iMachineNumber, 65535)) 31 { 32 this.axCZKEM1.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx); 33 Console.WriteLine("Connected"); 34 } 35 else 36 { 37 Console.WriteLine("Error"); 38 } 39 } 40 41 //加不加都不行 42 //while(true) 43 //{ 44 // sleep(1000); 45 //} 46 } 47 48 private void axCZKEM1_OnAttTransactionEx(string sEnrollNumber, int iIsInValid, int iAttState, int iVerifyMethod, int iYear, int iMonth, int iDay, int iHour, int iMinute, int iSecond, int iWorkCode) 49 { 50 Console.WriteLine("RTEvent OnAttTrasactionEx Has been Triggered,Verified OK"); 51 Console.WriteLine("...UserID:" + sEnrollNumber); 52 Console.WriteLine("...isInvalid:" + iIsInValid.ToString()); 53 Console.WriteLine("...attState:" + iAttState.ToString()); 54 Console.WriteLine("...VerifyMethod:" + iVerifyMethod.ToString()); 55 Console.WriteLine("...Workcode:" + iWorkCode.ToString());//the difference between the event OnAttTransaction and OnAttTransactionEx 56 Console.WriteLine("...Time:" + iYear.ToString() + "-" + iMonth.ToString() + "-" + iDay.ToString() + " " + iHour.ToString() + ":" + iMinute.ToString() + ":" + iSecond.ToString()); 57 } 58 } 59 60 }
这个SDK到底是什么原理,它实例化之后是否就附加在实例化它的那个线程上?线程回收了,它也就回收了?
这SDK是否自己会新建线程用于响应事件?为什么在winform下就能响应,而新建线程就不行呢?
本人野路子,没有学习过,纯属个人爱好,不要吐槽以上文字,理解意思就行。。
通过在启动线程里加入applation.run解决
貌似com组件通过内置的隐藏窗口消息来通信
application.run 就是在当前线程上启用消息循环
这个玩意儿 zkemkeeper.CZKEMClass 是个 COM 组件吗?
是的
@Launcher: 应该有联系 我好好看看 之前调试的时候 就发现线程必须设置为STA才行 MTA就报错
@Launcher: 也就是说STA COM里有一个隐藏的消息队列?
这个指定线程为STA的操作之前调试的时候就是有的,还是不行
如果仅仅调用方法,都是没问题的,就是这个事件响应不了
@我是大黄:
class Program { public static zkemkeeper.CZKEMClass sdk; static void Main(string[] args) { Thread t = new Thread(new ThreadStart(CreateSDK)); t.ApartementState = ApartmentState.STA; t.Start(); } static void CreateSDK() { sdk = new zkemkeeper.CZKEMClass(); sdk.RegEvent(imachineNumber,65535); sdk.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx); } static void axCZKEM1_OnAttTransactionEx(){} }
@Launcher: 十分感谢 我试一下看看
@Launcher: 貌似这样也不行,不过已经解决了,还是十分感谢
@我是大黄: 您好,我也遇到了一样的问题,能问下您是怎么解决的吗?
@chaojie: 饿,上面多线程里test方法最后加一句applation.run()
@我是大黄: 谢谢!!!
@我是大黄: 您好,请问你的问题是怎么解决的啊 我也碰到这个问题 触发不了事件 头疼死了
Console没有applation.run()呀
我也碰到这个问题,想请教你一下是怎么解决的呢?
您好 我现在也碰到这个问题,你是怎么解决的 事件触发不了
我怎么也注册不了事件 在控制台程序中注册定时器都不行 求解啊
连接 多台机器只需要new 多个CZKEMClass对象即可
您好,我的机器是H10,程序连接机器,读取用户数据等都没问题,只有注册实时事件失败,有遇到过么?
H10是USB设备连接的吧,是没有实时的,只有TCP连接的才有
还有什么方法可以解决的吗?
看我楼下发的信息,有链接,里面有源码实现
这是我这2天看完这文章写得代码,我按我这边需求调整了下. 我这里采取带参数启动了程序, 默认不带参数是winform ,带参数后,我自己做了2给动作,一个是同步数据(抽取考勤机的数据到数据库),另一个就是上面的利用返回事件,监控人员打卡信息,最后发送邮箱到指定邮箱. 首先我们要把入口点的 static void Main(string[] args) 上面的 [STAThread] 注释掉. 代码自己看,还没完善,我看着几天有人问题,我先放上来... http://pan.baidu.com/s/1c2qzutM
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Windows.Forms; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { test ts = new test(); ts.Connect(); } } public class test { public void Connect() { string[,] arr = new string[,] { { "192.168.1.81", "4370" }, { "192.168.1.85", "4370" } }; Thread[] tharr = new Thread[arr.Length / 2]; for (int i = 0; i < arr.Length / 2; i++) { ThreadA ta = new ThreadA(); ta.IpAddress = arr[i, 0]; ta.IpPort = int.Parse(arr[i, 1]); Thread thread = new Thread(new ThreadStart(ta.test)); thread.Start(); tharr[i] = thread; } Console.ReadKey(); } } public class ThreadA { public zkemkeeper.CZKEMClass axCZKEM1 = new zkemkeeper.CZKEMClass(); public bool bIsConnected = false;//the boolean value identifies whether the device is connected public int iMachineNumber = 1;//the serial number of the device.After connecting the device ,this value will be changed. public string IpAddress { get; set; } public int IpPort { get; set; } public void test() { bIsConnected = axCZKEM1.Connect_Net(IpAddress, IpPort); if (bIsConnected == true) { iMachineNumber = 1; if (axCZKEM1.RegEvent(iMachineNumber, 65535)) { this.axCZKEM1.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx); Console.WriteLine("Connected"); } else { Console.WriteLine("Error"); } } Application.Run(); //加不加都不行 //while(true) //{ // sleep(1000); //} } private void axCZKEM1_OnAttTransactionEx(string sEnrollNumber, int iIsInValid, int iAttState, int iVerifyMethod, int iYear, int iMonth, int iDay, int iHour, int iMinute, int iSecond, int iWorkCode) { Console.WriteLine("RTEvent OnAttTrasactionEx Has been Triggered,Verified OK"); Console.WriteLine("...UserID:" + sEnrollNumber); Console.WriteLine("...isInvalid:" + iIsInValid.ToString()); Console.WriteLine("...attState:" + iAttState.ToString()); Console.WriteLine("...VerifyMethod:" + iVerifyMethod.ToString()); Console.WriteLine("...Workcode:" + iWorkCode.ToString());//the difference between the event OnAttTransaction and OnAttTransactionEx Console.WriteLine("...Time:" + iYear.ToString() + "-" + iMonth.ToString() + "-" + iDay.ToString() + " " + iHour.ToString() + ":" + iMinute.ToString() + ":" + iSecond.ToString()); } } }
@zhr008:
首先我这个是window服务运行的,用winfrom窗口是有实时事件的,但服务不行,按照你这个也不见有触发。
什么问题啊?