考勤機是m880,需要在考勤機中設置保存考勤時照片。
SDK的開發文檔中只有下載考勤記錄的函數
ReadGeneralLogData
SSR_GetGeneralLogData
兩者配合能讀取到打卡記錄。
文檔中沒有下載考勤照片的函數,在代碼提示中查看photo。發現以下三個函數
public virtual bool GetPhotoNamesByTime(int dwMachineNumber, int iFlag, string sTime, string eTime, out string AllPhotoName);
public virtual bool GetPhotoCount(int dwMachineNumber, out int count, int iFlag);
public virtual bool GetPhotoByName(int dwMachineNumber, string PhotoName, out byte PhotoData, out int PhotoLength);
根據名字可以猜到功能。
GetPhotoNamesByTime讀取考勤機中的照片名列表,照片名命名規則是時間+考勤號,多個名字用'\t'分隔。
GetPhotoByName根據名字下載照片。
但是在代碼中如下調用時,失敗,返回錯誤碼-2
byte photoData; int photolength = 0; //////照片名需要加上“.jpg” axCZKEM1.GetPhotoByName(iMachineNumber,"20150910063045" + ".jpg", out photoData, out photolength)
找中控的售后,沒人理。只能靠自己了。
用Wireshark分析電腦和考勤機的通訊,發現考勤機已經正確返回了照片的數據,照片數據是二進制數據。
GetPhotoByName函數的參數是out photoData,這個應該保存照片數據。
問題在於photoData是byte類型的,照片的二進制數據應該是byte[]類型。調用函數造成了向內存中非法寫入數據。
想了個非常規的解決方法
unsafe { byte[] photoData = new byte[1024 * 10]; int photolength = 0; try { if (axCZKEM1.GetPhotoByName(iMachineNumber, arr[j].Trim() + ".jpg", out photoData[0], out photolength)) { if (photolength < photoData.Length) { byte[] tmp = new byte[photolength]; Array.Copy(photoData, tmp, photolength); System.IO.File.WriteAllBytes( "d:\\photos\\20150910063045.jpg", tmp); } } } catch (Exception ex) { } }
最后在項目的屬性里設置:允許不安全代碼。