using Admin.Core.Common;
using Aucma.Core.Scanner;
using log4net;
using MvCodeReaderSDKNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Aucma.Core.CodeBinding.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();
        // mes扫码器ip
        private static string LinerScannerIp = allScanners.First(x => x.Name == "mes扫码器").Ip;
        // sn扫码器ip
        private static string ShellScannerIp = allScanners.First(x => x.Name == "sn扫码器").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;

        private static string MesCode = string.Empty;
        private static string SNCode = string.Empty;

        #endregion


        #region 委托事件


        #region 条码绑定上位机委托事件



        /// <summary>
        /// 刷新扫码器状态
        /// </summary>
        /// <param name="materialCodeStr"></param>
        /// <param name="ip"></param>
        public delegate void RefreshState(string ip, bool flag);
        public static event RefreshState RefreshStateEvent;



        /// <summary>
        /// code1扫码信息刷新
        /// </summary>
        /// <param name="Code1"></param>
        public delegate void ReceiveCode(string code, string ip);
        public static event ReceiveCode? ReceiveCodeEvent;

        /// <summary>
        /// 条码绑定
        /// </summary>
        /// <param name="Code1"></param>
        public delegate void BindingCode(string mesCode, string snCode);
        public static event BindingCode? BindingCodeEvent;

        /// <summary>
        /// NoRead通知
        /// </summary>
        /// <param name="Code1"></param>
        public delegate void NoRead(string ip);
        public static event NoRead? NoReadEvent;


        #endregion

        /// <summary>
        /// 日志信息刷新
        /// </summary>
        /// <param name="message"></param>
        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)
            {
                NoReadEvent?.Invoke(ShellScannerIp);
                Console.WriteLine(DateTime.Now + ":SN--->No Read 处理");
                log.Info(DateTime.Now + ":SN--->No Read 处理");
                //更新扫码器存活时间
                ShellLiveTime = DateTime.Now;
                SNCode = string.Empty;
                MesCode = string.Empty;
            }
            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 + ":SN扫码器==>Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]");
                    log.Info(DateTime.Now + ":SN扫码器==>Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]");

                    //更新扫码器存活时间
                    ShellLiveTime = DateTime.Now;

                    SNCode = strCode.Trim().TrimEnd('\0');
                    ReceiveCodeEvent?.Invoke(strCode.Trim().TrimEnd('\0'), ShellScannerIp);
                    

                }
            }

            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)
        {
            try
            {
                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)
                {
                    NoReadEvent?.Invoke(LinerScannerIp);
                    Console.WriteLine(DateTime.Now + ":mes--->No Read 处理");
                    log.Info(DateTime.Now + ":mes--->No Read 处理");
                    // 更新存活时间
                    LinerLiveTime = DateTime.Now;
                    SNCode = string.Empty;
                    MesCode = string.Empty;
                }
                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 + ":mes扫码器==>Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]");
                        log.Info(DateTime.Now + ":mes扫码器==>Get CodeNum: " + "CodeNum[" + i.ToString() + "], CodeString[" + strCode.Trim().TrimEnd('\0') + "]");

                        // 更新存活时间
                        LinerLiveTime = DateTime.Now;

                        MesCode = strCode.Trim().TrimEnd('\0');
                        ReceiveCodeEvent?.Invoke(strCode.Trim().TrimEnd('\0'), LinerScannerIp);

                        if (!string.IsNullOrEmpty(MesCode) && !string.IsNullOrEmpty(SNCode))
                        {
                            BindingCodeEvent?.Invoke(MesCode, SNCode);
                            MesCode = string.Empty;
                            SNCode = string.Empty;
                        }

                    }
                }

                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') + "]");
                }
            }
            catch (Exception ex)
            {
                log.Info("mes扫码器回调函数异常:" + ex.Message.ToString());
            }
            finally
            {
                MesCode = string.Empty;
                SNCode = string.Empty;
            }
        }


        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("SN", false);

                    RefreshStateEvent?.Invoke("mes", 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("SN", false);

                    RefreshStateEvent?.Invoke("mes", 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("未找到SN扫码器");
                    // 刷新扫码器状态
                    RefreshStateEvent?.Invoke("SN", 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("SN", 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("SN", false);
                    break;
                }

                // 刷新扫码器状态
                RefreshStateEvent?.Invoke("SN", 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("SN", 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("SN", 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("SN扫码器超时");
                        //CloseShell();
                        //Shell();
                        break;
                    }

                }
                // Console.ReadLine();
                // 刷新扫码器状态
                RefreshStateEvent?.Invoke("SN", 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);
            Thread.Sleep(1000);
            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);
            //    }
            //}

        }



        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("SN", false);

                    RefreshStateEvent?.Invoke("mes", 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("SN", false);

                    RefreshStateEvent?.Invoke("mes", 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("未找到mes扫码器");
                    // 刷新扫码器状态
                    RefreshStateEvent?.Invoke("mes", 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("SN", false);
                    break;
                }
                // 刷新扫码器状态
                RefreshStateEvent?.Invoke("mes", 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("mes扫码器超时");
                        //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);
                }
            }
            Thread.Sleep(1000);
            Liner();

        }

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

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


        #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


    }
}