using MvCodeReaderSDKNet; using System.Runtime.InteropServices; using System.Text; namespace Aucma.Core.Scanner { /// /// 扫码器初始化 /// public class ScannerService : IScannerService { int nRet = MvCodeReader.MV_CODEREADER_OK; MvCodeReader device = new MvCodeReader(); public ScannerService() { } public async Task StartScannerAsync() { await StartServer(); } #region 获取设备个数 /// /// 获取设备个数 /// /// public Task GetDevNum() { 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); return Task.FromResult(0); } int deviceNum = Convert.ToInt32(stDevList.nDeviceNum); return Task.FromResult(deviceNum); } #endregion #region 获取设备列表 /// /// 获取设备个数 /// /// public MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST GetDevList() { 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); return stDevList; } #endregion #region 获取设备信息 /// /// 获取设备个数 /// /// public async Task GetDevInfo() { List list=new List(); byte[] chUserDefinedName = null; MvCodeReader.MV_CODEREADER_DEVICE_INFO stDevInfo;// 通用设备信息 MvCodeReader.MV_CODEREADER_DEVICE_INFO_LIST stDevList = GetDevList(); int deviceNum =await GetDevNum(); for (int i = 0; i < deviceNum; 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); //chUserDefinedName = Encoding.GetEncoding("GB2312").GetBytes(stGigEDeviceInfo.chUserDefinedName); chUserDefinedName = System.Text.Encoding.Default.GetBytes(stGigEDeviceInfo.chUserDefinedName); string strUserDefinedName = Encoding.UTF8.GetString(chUserDefinedName); Console.WriteLine("\n" + i.ToString() + ": [GigE] User Define Name : " + strUserDefinedName); Console.WriteLine("device IP :" + nIp1 + "." + nIp2 + "." + nIp3 + "." + nIp4); } else if (MvCodeReader.MV_CODEREADER_USB_DEVICE == stDevInfo.nTLayerType) { MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO stUsb3DeviceInfo = (MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO)MvCodeReader.ByteToStruct(stDevInfo.SpecialInfo.stUsb3VInfo, typeof(MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO)); //chUserDefinedName = Encoding.GetEncoding("GB2312").GetBytes(stUsb3DeviceInfo.chUserDefinedName); chUserDefinedName = System.Text.Encoding.Default.GetBytes(stUsb3DeviceInfo.chUserDefinedName); string strUserDefinedName = Encoding.UTF8.GetString(chUserDefinedName); Console.WriteLine("\n" + i.ToString() + ": [U3V] User Define Name : " + strUserDefinedName); Console.WriteLine("\n 序列号 : " + stUsb3DeviceInfo.chSerialNumber); Console.WriteLine("\n 设备号 : " + stUsb3DeviceInfo.nDeviceNumber); } } } #endregion public Task StartServer() { 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("枚举设备失败:{0:x8}", nRet); continue; } int deviceNum = Convert.ToInt32(stDevList.nDeviceNum); Console.WriteLine("Enum device count : " + Convert.ToString(stDevList.nDeviceNum)); if (0 == stDevList.nDeviceNum) { continue; } MvCodeReader.MV_CODEREADER_DEVICE_INFO stDevInfo; // 通用设备信息 byte[] chUserDefinedName = null; // 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); //chUserDefinedName = Encoding.GetEncoding("GB2312").GetBytes(stGigEDeviceInfo.chUserDefinedName); chUserDefinedName = System.Text.Encoding.Default.GetBytes(stGigEDeviceInfo.chUserDefinedName); string strUserDefinedName = Encoding.UTF8.GetString(chUserDefinedName); Console.WriteLine("\n" + i.ToString() + ": [GigE] 用户定义名称 : " + strUserDefinedName); Console.WriteLine("设备IP:" + nIp1 + "." + nIp2 + "." + nIp3 + "." + nIp4); } else if (MvCodeReader.MV_CODEREADER_USB_DEVICE == stDevInfo.nTLayerType) { MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO stUsb3DeviceInfo = (MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO)MvCodeReader.ByteToStruct(stDevInfo.SpecialInfo.stUsb3VInfo, typeof(MvCodeReader.MV_CODEREADER_USB3_DEVICE_INFO)); //chUserDefinedName = Encoding.GetEncoding("GB2312").GetBytes(stUsb3DeviceInfo.chUserDefinedName); chUserDefinedName = System.Text.Encoding.Default.GetBytes(stUsb3DeviceInfo.chUserDefinedName); string strUserDefinedName = Encoding.UTF8.GetString(chUserDefinedName); Console.WriteLine("\n" + i.ToString() + ": [U3V] 用户定义名称 : " + strUserDefinedName); Console.WriteLine("\n 序列号 : " + stUsb3DeviceInfo.chSerialNumber); Console.WriteLine("\n 设备号 : " + stUsb3DeviceInfo.nDeviceNumber); } } int nDevIndex = 0; 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("创建设备失败:{0:x8}", nRet); continue; } // ch:打开设备 | en:Open device nRet = device.MV_CODEREADER_OpenDevice_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("打开设备失败:{0:x8}", nRet); continue; } // ch:设置触发模式为off || en:set trigger mode as off if (MvCodeReader.MV_CODEREADER_OK != device.MV_CODEREADER_SetEnumValue_NET("TriggerMode", 0)) { Console.WriteLine("设置触发模式失败!"); continue; } // ch:开启抓图 | en:start grab nRet = device.MV_CODEREADER_StartGrabbing_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("启动抓取失败:{0:x8}", nRet); continue; } int nCount = 0; IntPtr pBufForDriver = IntPtr.Zero; MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2 stFrameInfo = new MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2(); IntPtr pstFrameInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2))); Marshal.StructureToPtr(stFrameInfo, pstFrameInfo, false); //while (nCount++ != 20) //{ nRet = device.MV_CODEREADER_GetOneFrameTimeoutEx2_NET(ref pBufForDriver, pstFrameInfo, 1000); // ch:获取一帧图像 | en:Get one image if (MvCodeReader.MV_CODEREADER_OK == nRet) { stFrameInfo = (MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2)Marshal.PtrToStructure(pstFrameInfo, typeof(MvCodeReader.MV_CODEREADER_IMAGE_OUT_INFO_EX2)); Console.WriteLine("获取一帧:" + "nChannelID[" + Convert.ToString(stFrameInfo.nChannelID) + "] , Width[" + Convert.ToString(stFrameInfo.nWidth) + "], Height[" + Convert.ToString(stFrameInfo.nHeight) + "] , FrameNum[" + Convert.ToString(stFrameInfo.nFrameNum) + "]"); // 分配条码内存空间 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)); //String strCode = System.Text.Encoding.Default.GetString(stBcrResultEx2.stBcrInfoEx2[i].chCode); Console.WriteLine("获取CodeNum:" + "CodeNum[" + Convert.ToString(stBcrResult.nCodeNum) + "]"); for (int i = 0; i < stBcrResult.nCodeNum; ++i) { bool bIsValidUTF8 = IsTextUTF8(stBcrResult.stBcrInfoEx2[i].chCode); if (bIsValidUTF8) { string strCode = System.Text.Encoding.Default.GetString(stBcrResult.stBcrInfoEx2[i].chCode); // 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); string strCode = System.Text.Encoding.Default.GetString(stBcrResult.stBcrInfoEx2[i].chCode); Console.WriteLine("Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + 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); string strOcrCharCode = System.Text.Encoding.Default.GetString(stOcrInfo.stOcrRowInfo[i].chOcr); Console.WriteLine("Get OcrInfo:" + "ocrNum[" + i.ToString() + "], ocrLen[" + Convert.ToString(stOcrInfo.stOcrRowInfo[i].nOcrLen) + "], ocrChar[" + strOcrCharCode.Trim().TrimEnd('\0') + "]"); } } else { Console.WriteLine("没有数据:{0:x8}", nRet); continue; } //} // ch:停止抓图 | en:Stop grab image nRet = device.MV_CODEREADER_StopGrabbing_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("停止抓取失败{0:x8}", nRet); continue; } } while (false); return Task.CompletedTask; } #region 销毁设备 /// /// 销毁设备 /// public void Destroy() { // ch:关闭设备 | en:Close device nRet = device.MV_CODEREADER_CloseDevice_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("关闭设备失败{0:x8}", nRet); } // ch:销毁设备 | en:Destroy device nRet = device.MV_CODEREADER_DestroyHandle_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("销毁设备失败:{0:x8}", nRet); } if (MvCodeReader.MV_CODEREADER_OK != nRet) { // ch:销毁设备 | en:Destroy device nRet = device.MV_CODEREADER_DestroyHandle_NET(); if (MvCodeReader.MV_CODEREADER_OK != nRet) { Console.WriteLine("销毁设备失败:{0:x8}", nRet); } } } #endregion #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 } }