You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

388 lines
16 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Admin.Core.Common;
using Aucma.Core.Scanner;
using log4net;
using MvCodeReaderSDKNet;
using NPOI.SS.Formula.Functions;
using StackExchange.Profiling;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UAParser;
namespace Aucma.Core.DoorFoam.Business
{
public class MvCodeHelper
{
//private static AppConfig appConfig = AppConfig.Instance;
public static bool m_bGrabbing = true;
private static string lastCode;
private static List<ScannerModel> allScanners = Appsettings.app<ScannerModel>("ScannerServer").ToList();
// 内胆扫码器ip
private static string doorScannerIp = allScanners.First(x => x.Name == "扫码器1").Ip;
private static readonly log4net.ILog log = LogManager.GetLogger(typeof(MvCodeHelper));
#region 全局变量定义
public static MvCodeReader doorDevice = null;
public static DateTime doorLiveTime = DateTime.Now;
#endregion
#region 委托事件
/// <summary>
/// 门体匹配扫码
/// </summary>
/// <param name="Code1"></param>
public delegate Task DoorReceiveCodeDelegate(string code1);
public static event DoorReceiveCodeDelegate? DoorReceiveCodeDelegateEvent;
/// <summary>
/// 刷新扫码器状态
/// </summary>
/// <param name="materialCodeStr"></param>
/// <param name="ip"></param>
public delegate void RefreshState(string ip, bool flag);
public static event RefreshState RefreshStateEvent;
/// <summary>
/// 日志信息刷新
/// </summary>
/// <param name="message"></param>
public delegate void RefreshLogMessage(string message);
public static event RefreshLogMessage RefreshLogMessageEvent;
#endregion
public static void DoorImageCallbackFunc(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)
{
Console.WriteLine(DateTime.Now+":门体匹配--->No Read 处理");
//log.Info(DateTime.Now + ":门体匹配--->No Read 处理");
// 更新存活时间
doorLiveTime = DateTime.Now;
}
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(DateTime.Now + ":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') + "]");
log.Info(DateTime.Now + ":箱门匹配扫码器==>Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]");
// RefreshMaterialCodeStrEvent?.Invoke(strCode.Trim().TrimEnd('\0'), LinerScannerIp);
if (!string.IsNullOrEmpty(strCode.Trim().TrimEnd('\0')))
{
// 更新存活时间
doorLiveTime = DateTime.Now;
// 业务处理
DoorReceiveCodeDelegateEvent?.Invoke(strCode.Trim().TrimEnd('\0'));
}
else
{
// 更新存活时间
doorLiveTime = DateTime.Now;
Console.WriteLine(DateTime.Now + "箱门匹配扫码器==>条码:" + strCode.Trim().TrimEnd('\0') + "长度不为20当做No Read 处理");
log.Info(DateTime.Now + "箱门匹配扫码器==>条码:" + strCode.Trim().TrimEnd('\0') + "长度不为20当做No Read 处理");
}
}
}
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 Task Door()
{
doorLiveTime = DateTime.Now;
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)
{
// 刷新扫码器状态
RefreshStateEvent?.Invoke("箱门匹配", false);
Thread.Sleep(1000 * 10);
Console.WriteLine("Enum device failed:{0:x8}", nRet);
break;
}
Console.WriteLine("Enum device count : " + Convert.ToString(stDevList.nDeviceNum));
if (0 == stDevList.nDeviceNum)
{
// 刷新扫码器状态
RefreshStateEvent?.Invoke("箱门匹配", false);
Thread.Sleep(1000 * 10);
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 ==doorScannerIp)
{
Console.WriteLine("device IP :" + ipStr);
nDevIndex = i;
}
}
}
if (nDevIndex < 0)
{
Console.WriteLine("未找到箱门匹配扫码器");
// 刷新扫码器状态
RefreshStateEvent?.Invoke("箱门匹配", false);
Thread.Sleep(1000 * 30);
break;
}
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);
// 刷新扫码器状态
RefreshStateEvent?.Invoke("箱门匹配", false);
break;
}
// 刷新扫码器状态
RefreshStateEvent?.Invoke("箱门匹配", true);
// ch:注册回调函数 | en:Register image callback
ImageCallback = new MvCodeReader.cbOutputEx2delegate(DoorImageCallbackFunc);
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.WriteLine(DateTime.Now.ToString());
while (true)
{
Thread.Sleep(1000*60);
DateTime dateTime = DateTime.Now;
TimeSpan timeSpan = dateTime.Subtract(doorLiveTime);
if (timeSpan.TotalMinutes >= 10)
{
Console.WriteLine("箱门匹配扫码器超时");
break;
}
}
//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);
}
}
Thread.Sleep(1000);
Door();
return Task.CompletedTask;
}
/// <summary>
/// 关闭内胆扫码器
/// </summary>
public static void CloseDoor()
{
int nRet = MvCodeReader.MV_CODEREADER_OK;
MvCodeReader device = doorDevice;
// ch:停止抓图 | en:Stop grabbing
nRet = device.MV_CODEREADER_StopGrabbing_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("Stop grabbing failed{0:x8}", nRet);
return;
}
// ch:关闭设备 | en:Close device
nRet = device.MV_CODEREADER_CloseDevice_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("Close device failed{0:x8}", nRet);
return;
}
// ch:销毁设备 | en:Destroy device
nRet = device.MV_CODEREADER_DestroyHandle_NET();
if (MvCodeReader.MV_CODEREADER_OK != nRet)
{
Console.WriteLine("Destroy device failed:{0:x8}", nRet);
return;
}
Console.WriteLine("关闭内胆扫码器成功");
return;
}
#region 判断字符编码
/// <summary>
/// 判断字符编码
/// </summary>
/// <param name="inputStream"></param>
/// <returns></returns>
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
}
}