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.Palletiz.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();
        // 10.10.92.230扫码器ip
        private static string LinerScannerIp = allScanners.First(x => x.Name == "PalletizStoreCodeA").Ip;
        // 10.10.92.231扫码器ip
        private static string ShellScannerIp = allScanners.First(x => x.Name == "APalletizStoreCodeB2").Ip;

        private static readonly log4net.ILog log = LogManager.GetLogger(typeof(MvCodeHelper));


        #region 全局变量定义
       public static MvCodeReader ShellDevice = null;
       public static MvCodeReader LinerDevice = null;
       public static DateTime ShellLiveTime = DateTime.Now;
       public static DateTime LinerLiveTime = DateTime.Now;
        #endregion

        #region 委托事件

        /// <summary>
        /// 成品入库委托
        /// </summary>
        /// <param name="materialCodeStr"></param>
        /// <param name="ip"></param>
        public delegate void RefreshPalletizDelegate(string materialCodeStr, string ip);
        public static event RefreshPalletizDelegate RefreshPalletizDelegateEvent;

        /// <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

        #region   +ShellImageCallbackFunc(IntPtr pData, IntPtr pstFrameInfoEx2, IntPtr pUser)

        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)
            {
                Console.WriteLine(DateTime.Now + ":外侧--->No Read 处理");
                log.Info(DateTime.Now + ":外侧--->No Read 处理");
                //更新扫码器存活时间
                ShellLiveTime = 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'), ShellScannerIp);
                    if (strCode.Trim().TrimEnd('\0').Length == 20)
                    {
                        //更新扫码器存活时间
                        ShellLiveTime = DateTime.Now;
                        //RefreshMaterialCodeStrEvent?.Invoke(strCode.Trim().TrimEnd('\0'), ShellScannerIp);
                        // 业务处理
                        Console.WriteLine(strCode.Trim().TrimEnd('\0'), ShellScannerIp);
                    }
                    else
                    {
                        // 更新存活时间
                        LinerLiveTime = 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));

            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') + "]");
            }
        }


        #endregion

        #region + LinerImageCallbackFunc(IntPtr pData, IntPtr pstFrameInfoEx2, IntPtr pUser)

        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)
            {
                Console.WriteLine(DateTime.Now + ":内侧--->No Read 处理");
                log.Info(DateTime.Now + ":内侧--->No Read 处理");
                // 更新存活时间
                LinerLiveTime = 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 (strCode.Trim().TrimEnd('\0').Length == 20)
                    {
                        // 更新存活时间
                        LinerLiveTime = DateTime.Now;
                        // 业务处理
                        RefreshPalletizDelegateEvent?.Invoke(strCode.Trim().TrimEnd('\0'), LinerScannerIp);
                        //Console.WriteLine(strCode.Trim().TrimEnd('\0'), ShellScannerIp);
                    }
                    else
                    {
                        // 更新存活时间
                        LinerLiveTime = 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') + "]");
            }
        }

        #endregion

        #region Shell()
        public static void Shell()
        {
            ShellLiveTime = 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);

                    //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);

                    //RefreshStateEvent?.Invoke("内侧", false);
                    Thread.Sleep(1000 * 10);

                    break;
                }

                MvCodeReader.MV_CODEREADER_DEVICE_INFO stDevInfo;                            // 通用设备信息
                int 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)
                {
                    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);
                    // 刷新扫码器状态
                    RefreshStateEvent?.Invoke("外侧", false);
                    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(ShellImageCallbackFunc);
                nRet = device.MV_CODEREADER_RegisterImageCallBackEx2_NET(ImageCallback, IntPtr.Zero);
                if (MvCodeReader.MV_CODEREADER_OK != nRet)
                {
                    Console.WriteLine("Register image callback failed!");
                    // 刷新扫码器状态
                    //RefreshStateEvent?.Invoke("外侧", false);
                    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);
                    // 刷新扫码器状态
                    RefreshStateEvent?.Invoke("外侧", false);
                    break;
                }

                // 关闭使用
                ShellDevice = device;
                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(ShellLiveTime);
                    if (timeSpan.TotalMinutes >= 10)
                    {
                        Console.WriteLine("外侧扫码器超时");
                        //CloseShell();
                        //Shell();
                        break;
                    }

                }
                // Console.ReadLine();
                // 刷新扫码器状态
                //RefreshStateEvent?.Invoke("外侧", false);
                // 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);
            Shell();
            //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);
            //    }
            //}

        }

        #endregion

        #region Liner()
        public static void Liner()
        {
            LinerLiveTime = 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);

                    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);

                    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 == LinerScannerIp)
                        {
                            Console.WriteLine("device IP :" + ipStr);
                            nDevIndex = i;
                        }
                    }
                }
                if (nDevIndex < 0)
                {
                    Console.WriteLine("未找到10.10.92.230扫码器");
                    // 刷新扫码器状态
                    //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(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;
                }
                // 关闭使用
                ShellDevice = device;

                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(LinerLiveTime);
                    if (timeSpan.TotalMinutes >= 10)
                    {
                        Console.WriteLine("内侧扫码器超时");
                        //CloseShell();
                        //Shell();
                        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);
                }
            }
            Liner();

        }

        #endregion

        #region 关闭内胆扫码器
        /// <summary>
        /// 关闭内胆扫码器
        /// </summary>
        public static void CloseLiner()
        {
            int nRet = MvCodeReader.MV_CODEREADER_OK;
            MvCodeReader device = LinerDevice;
            // 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;
        }

        #endregion

        #region 关闭箱壳扫码器
        /// <summary>
        /// 关闭箱壳扫码器
        /// </summary>
        public static void CloseShell()
        {
            int nRet = MvCodeReader.MV_CODEREADER_OK;
            MvCodeReader device = ShellDevice;
            // 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;
        }

        #endregion

        #region 监测扫码器15分钟以内是否有触发操作,如果超时未触发,关闭再重连扫码器
        /// <summary>
        /// 监测扫码器15分钟以内是否有触发操作,如果超时未触发,关闭再重连扫码器
        /// </summary>
        public static void JudgeShellIsConnectedAndReConnect()
        {
            try
            {
                DateTime dateTime = DateTime.Now;
                TimeSpan timeSpan = dateTime.Subtract(ShellLiveTime);
                Task.Run(() =>
                {
                    if (timeSpan.TotalMinutes >= 1)
                    {
                        Console.WriteLine("箱壳扫码器超时,重连");
                        ShellLiveTime = dateTime;
                        CloseShell();
                        Shell();
                    }
                });
                Task.Run(() =>
                {
                    TimeSpan timeSpan2 = dateTime.Subtract(LinerLiveTime);
                    if (timeSpan2.TotalMinutes >= 1)
                    {
                        Console.WriteLine("内胆扫码器超时,重连");
                        LinerLiveTime = dateTime;
                        CloseLiner();
                        Liner();
                    }
                });

            }
            catch (Exception ex)
            {
                log.Error("JudgeShellIsConnectedAndReConnect判断扫码器重连方法异常:" + ex.Message.ToString());
            }

        }

        #endregion

        #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


    }
}