using MvCodeReaderSDKNet; using System; using System.Collections.Generic; using System.Drawing; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Threading; using static System.Runtime.CompilerServices.RuntimeHelpers; using HighWayIot.Log4net; using HighWayIot.Config; using System.Security.Policy; namespace Aucma.Core.Scanner { public class MvCodeHelper2 { private static AppConfig appConfig = AppConfig.Instance; public static bool m_bGrabbing = true; private static string SheellLastCode; private static string LinerLastCode; // 内胆扫码器ip private static string LinerScannerIp = appConfig.linerHikRobotIp; // 箱壳扫码器ip private static string ShellScannerIp = appConfig.shellHikRobotIp; #region 全局变量定义 public static DateTime ShellLiveTime = DateTime.Now; public static DateTime LinerLiveTime = DateTime.Now; #endregion #region 委托事件 public delegate void RefreshMaterialCodeStr(string materialCodeStr, string ip); public static event RefreshMaterialCodeStr RefreshMaterialCodeStrEvent; //NoRead事件通知 public delegate void MessageNoRead(string storeCode); public static event MessageNoRead MessageNoReadEvent; /// /// 日志信息刷新 /// /// public delegate void RefreshLogMessage(string message); public static event RefreshLogMessage RefreshLogMessageEvent; #endregion public static void ShellImageCallbackFunc(IntPtr pData, IntPtr pstFrameInfoEx2, IntPtr pUser) { var stFrameInfo = (MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2)Marshal.PtrToStructure(pstFrameInfoEx2, typeof(MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2)); MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2 stBcrResult = (MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2)Marshal.PtrToStructure(stFrameInfo.UnparsedBcrList.pstCodeListEx2, typeof(MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2)); // Console.WriteLine("CodeNum[" + Convert.ToString(stBcrResult.nCodeNum) + "]"); if (stBcrResult.nCodeNum == 0) { //更新扫码器存活时间 ShellLiveTime = DateTime.Now; Console.WriteLine("No Read 处理"); MessageNoReadEvent(appConfig.shellStoreCode); } for (Int32 i = 0; i < stBcrResult.nCodeNum; i++) { bool bIsValidUTF8 = IsTextUTF8(stBcrResult.stBcrInfoEx2[i].chCode); if (bIsValidUTF8) { string strCode = Encoding.UTF8.GetString(stBcrResult.stBcrInfoEx2[i].chCode); Console.WriteLine("Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]"); } else { string strCode = Encoding.GetEncoding("GB2312").GetString(stBcrResult.stBcrInfoEx2[i].chCode); Console.WriteLine(DateTime.Now + ":箱壳扫码器==>Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]"); if (string.IsNullOrEmpty(SheellLastCode) || SheellLastCode != strCode.Trim().TrimEnd('\0')) { //更新扫码器存活时间 ShellLiveTime = DateTime.Now; RefreshMaterialCodeStrEvent?.Invoke(strCode.Trim().TrimEnd('\0'), ShellScannerIp); SheellLastCode = strCode.Trim().TrimEnd('\0'); } } } MvCodeReader.MV_CODEREADER_OCR_INFO_LIST stOcrInfo = (MvCodeReader.MV_CODEREADER_OCR_INFO_LIST)Marshal.PtrToStructure(stFrameInfo.UnparsedOcrList.pstOcrList, typeof(MvCodeReader.MV_CODEREADER_OCR_INFO_LIST)); for (int i = 0; i < stOcrInfo.nOCRAllNum; i++) { string strOcrCharCode = Encoding.UTF8.GetString(stOcrInfo.stOcrRowInfo[i].chOcr); Console.WriteLine("Get OcrInfo:" + "ocrNum[" + i.ToString() + "], ocrLen[" + Convert.ToString(stOcrInfo.stOcrRowInfo[i].nOcrLen) + "], ocrChar[" + strOcrCharCode.Trim().TrimEnd('\0') + "]"); } } public static void LinerImageCallbackFunc(IntPtr pData, IntPtr pstFrameInfoEx2, IntPtr pUser) { var stFrameInfo = (MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2)Marshal.PtrToStructure(pstFrameInfoEx2, typeof(MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2)); MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2 stBcrResult = (MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2)Marshal.PtrToStructure(stFrameInfo.UnparsedBcrList.pstCodeListEx2, typeof(MvCodeReader.MV_CODEREADER_RESULT_BCR_EX2)); // Console.WriteLine("CodeNum[" + Convert.ToString(stBcrResult.nCodeNum) + "]"); if (stBcrResult.nCodeNum == 0) { // 更新存活时间 LinerLiveTime = DateTime.Now; Console.WriteLine("No Read 处理"); MessageNoReadEvent(appConfig.linerStoreCode); } for (Int32 i = 0; i < stBcrResult.nCodeNum; i++) { bool bIsValidUTF8 = IsTextUTF8(stBcrResult.stBcrInfoEx2[i].chCode); if (bIsValidUTF8) { string strCode = Encoding.UTF8.GetString(stBcrResult.stBcrInfoEx2[i].chCode); Console.WriteLine("Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]"); } else { string strCode = Encoding.GetEncoding("GB2312").GetString(stBcrResult.stBcrInfoEx2[i].chCode); Console.WriteLine(DateTime.Now + ":内胆扫码器==>Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]"); if (string.IsNullOrEmpty(LinerLastCode) || LinerLastCode != strCode.Trim().TrimEnd('\0')) { // 更新存活时间 LinerLiveTime = DateTime.Now; RefreshMaterialCodeStrEvent?.Invoke(strCode.Trim().TrimEnd('\0'), LinerScannerIp); LinerLastCode = strCode.Trim().TrimEnd('\0'); } } } MvCodeReader.MV_CODEREADER_OCR_INFO_LIST stOcrInfo = (MvCodeReader.MV_CODEREADER_OCR_INFO_LIST)Marshal.PtrToStructure(stFrameInfo.UnparsedOcrList.pstOcrList, typeof(MvCodeReader.MV_CODEREADER_OCR_INFO_LIST)); Console.WriteLine("ocrAllNum[" + Convert.ToString(stOcrInfo.nOCRAllNum) + "]"); for (int i = 0; i < stOcrInfo.nOCRAllNum; i++) { string strOcrCharCode = Encoding.UTF8.GetString(stOcrInfo.stOcrRowInfo[i].chOcr); Console.WriteLine("Get OcrInfo:" + "ocrNum[" + i.ToString() + "], ocrLen[" + Convert.ToString(stOcrInfo.stOcrRowInfo[i].nOcrLen) + "], ocrChar[" + strOcrCharCode.Trim().TrimEnd('\0') + "]"); } } public static void Shell() { MvCodeReader.cbOutputEx2delegate ImageCallback; MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2 stFrameInfo = new MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2(); MvCodeReader device = new MvCodeReader(); int nRet = MvCodeReader.MV_CODEREADER_OK; do { // ch:枚举设备 | en:Enum device MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST stDevList = new MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST(); nRet = MvCodeReader.MV_CODEREADER_EnumDevices_NET(ref stDevList, MvCodeReader.MV_CODEREADER_GIGE_DEVICE); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Enum device failed:{0:x8}", nRet); break; } Console.WriteLine("Enum device count : " + Convert.ToString(stDevList.nDeviceNum)); if (0 == stDevList.nDeviceNum) { break; } MvCodeReader.MV_CODEREADER_DEVICE_INFO stDevInfo; // 通用设备信息 Int32 nDevIndex = -1; // ch:打印设备信息 | en:Print device info for (Int32 i = 0; i < stDevList.nDeviceNum; i++) { stDevInfo = (MvCodeReader.MV_CODEREADER_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MvCodeReader.MV_CODEREADER_DEVICE_INFO)); if (MvCodeReader.MV_CODEREADER_GIGE_DEVICE == stDevInfo.nTLayerType) { MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO stGigEDeviceInfo = (MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO)MvCodeReader.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO)); uint nIp1 = ((stGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24); uint nIp2 = ((stGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16); uint nIp3 = ((stGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8); uint nIp4 = (stGigEDeviceInfo.nCurrentIp & 0x000000ff); // Console.WriteLine("\n" + i.ToString() + ": [GigE] User Define Name : " + stGigEDeviceInfo.chUserDefinedName); // Console.WriteLine("device IP :" + nIp1 + "." + nIp2 + "." + nIp3 + "." + nIp4); string ipStr = nIp1 + "." + nIp2 + "." + nIp3 + "." + nIp4; if (ipStr == ShellScannerIp) { nDevIndex = i; Console.WriteLine("device IP :" + ipStr); } } } if (nDevIndex < 0) return; stDevInfo = (MvCodeReader.MV_CODEREADER_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[nDevIndex], typeof(MvCodeReader.MV_CODEREADER_DEVICE_INFO)); // ch:创建设备 | en:Create device nRet = device.MV_CODEREADER_CreateHandle_NET(ref stDevInfo); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Create device failed:{0:x8}", nRet); break; } // ch:打开设备 | en:Open device nRet = device.MV_CODEREADER_OpenDevice_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Open device failed:{0:x8}", nRet); break; } // ch:注册回调函数 | en:Register image callback ImageCallback = new MvCodeReader.cbOutputEx2delegate(ShellImageCallbackFunc); nRet = device.MV_CODEREADER_RegisterImageCallBackEx2_NET(ImageCallback, IntPtr.Zero); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Register image callback failed!"); break; } // ch:开启抓图 || en: start grab image nRet = device.MV_CODEREADER_StartGrabbing_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Start grabbing failed:{0:x8}", nRet); break; } Console.WriteLine("Press enter to exit"); Console.ReadLine(); // ch:停止抓图 | en:Stop grabbing nRet = device.MV_CODEREADER_StopGrabbing_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Stop grabbing failed{0:x8}", nRet); break; } // ch:关闭设备 | en:Close device nRet = device.MV_CODEREADER_CloseDevice_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Close device failed{0:x8}", nRet); break; } // ch:销毁设备 | en:Destroy device nRet = device.MV_CODEREADER_DestroyHandle_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Destroy device failed:{0:x8}", nRet); break; } } while (false); if (MvCodeReader.MV_CODEREADER_OK != nRet) { // ch:销毁设备 | en:Destroy device nRet = device.MV_CODEREADER_DestroyHandle_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Destroy device failed:{0:x8}", nRet); } } } public static void Liner() { MvCodeReader.cbOutputEx2delegate ImageCallback; MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2 stFrameInfo = new MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2(); MvCodeReader device = new MvCodeReader(); int nRet = MvCodeReader.MV_CODEREADER_OK; do { // ch:枚举设备 | en:Enum device MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST stDevList = new MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST(); nRet = MvCodeReader.MV_CODEREADER_EnumDevices_NET(ref stDevList, MvCodeReader.MV_CODEREADER_GIGE_DEVICE); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Enum device failed:{0:x8}", nRet); break; } Console.WriteLine("Enum device count : " + Convert.ToString(stDevList.nDeviceNum)); if (0 == stDevList.nDeviceNum) { break; } MvCodeReader.MV_CODEREADER_DEVICE_INFO stDevInfo; // 通用设备信息 Int32 nDevIndex = -1; // ch:打印设备信息 | en:Print device info for (Int32 i = 0; i < stDevList.nDeviceNum; i++) { stDevInfo = (MvCodeReader.MV_CODEREADER_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MvCodeReader.MV_CODEREADER_DEVICE_INFO)); if (MvCodeReader.MV_CODEREADER_GIGE_DEVICE == stDevInfo.nTLayerType) { MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO stGigEDeviceInfo = (MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO)MvCodeReader.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MvCodeReader.MV_CODEREADER_GIGE_DEVICE_INFO)); uint nIp1 = ((stGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24); uint nIp2 = ((stGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16); uint nIp3 = ((stGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8); uint nIp4 = (stGigEDeviceInfo.nCurrentIp & 0x000000ff); // Console.WriteLine("\n" + i.ToString() + ": [GigE] User Define Name : " + stGigEDeviceInfo.chUserDefinedName); string ip = ((stGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24) + "." + ((stGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16) + "." + ((stGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8) + "." + (stGigEDeviceInfo.nCurrentIp & 0x000000ff); string ipStr = nIp1 + "." + nIp2 + "." + nIp3 + "." + nIp4; if (ipStr == LinerScannerIp) { Console.WriteLine("device IP :" + ipStr); nDevIndex = i; } } } if (nDevIndex < 0) return; stDevInfo = (MvCodeReader.MV_CODEREADER_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[nDevIndex], typeof(MvCodeReader.MV_CODEREADER_DEVICE_INFO)); // ch:创建设备 | en:Create device nRet = device.MV_CODEREADER_CreateHandle_NET(ref stDevInfo); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Create device failed:{0:x8}", nRet); break; } // ch:打开设备 | en:Open device nRet = device.MV_CODEREADER_OpenDevice_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Open device failed:{0:x8}", nRet); break; } // ch:注册回调函数 | en:Register image callback ImageCallback = new MvCodeReader.cbOutputEx2delegate(LinerImageCallbackFunc); nRet = device.MV_CODEREADER_RegisterImageCallBackEx2_NET(ImageCallback, IntPtr.Zero); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Register image callback failed!"); break; } // ch:开启抓图 || en: start grab image nRet = device.MV_CODEREADER_StartGrabbing_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Start grabbing failed:{0:x8}", nRet); break; } Console.WriteLine("Press enter to exit"); Console.ReadLine(); // ch:停止抓图 | en:Stop grabbing nRet = device.MV_CODEREADER_StopGrabbing_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Stop grabbing failed{0:x8}", nRet); break; } // ch:关闭设备 | en:Close device nRet = device.MV_CODEREADER_CloseDevice_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Close device failed{0:x8}", nRet); break; } // ch:销毁设备 | en:Destroy device nRet = device.MV_CODEREADER_DestroyHandle_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Destroy device failed:{0:x8}", nRet); break; } } while (false); if (MvCodeReader.MV_CODEREADER_OK != nRet) { // ch:销毁设备 | en:Destroy device nRet = device.MV_CODEREADER_DestroyHandle_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("Destroy device failed:{0:x8}", nRet); } } } #region 判断字符编码 /// /// 判断字符编码 /// /// /// public static bool IsTextUTF8(byte[] inputStream) { int encodingBytesCount = 0; bool allTextsAreASCIIChars = true; for (int i = 0; i < inputStream.Length; i++) { byte current = inputStream[i]; if ((current & 0x80) == 0x80) { allTextsAreASCIIChars = false; } // First byte if (encodingBytesCount == 0) { if ((current & 0x80) == 0) { // ASCII chars, from 0x00-0x7F continue; } if ((current & 0xC0) == 0xC0) { encodingBytesCount = 1; current <<= 2; // More than two bytes used to encoding a unicode char. // Calculate the real length. while ((current & 0x80) == 0x80) { current <<= 1; encodingBytesCount++; } } else { // Invalid bits structure for UTF8 encoding rule. return false; } } else { // Following bytes, must start with 10. if ((current & 0xC0) == 0x80) { encodingBytesCount--; } else { // Invalid bits structure for UTF8 encoding rule. return false; } } } if (encodingBytesCount != 0) { // Invalid bits structure for UTF8 encoding rule. // Wrong following bytes count. return false; } // Although UTF8 supports encoding for ASCII chars, we regard as a input stream, whose contents are all ASCII as default encoding. return !allTextsAreASCIIChars; } #endregion } }