RemoteDecodeHelper.cs 6.0 KB
using CodeLibrary;
using HalconDotNet;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;

public class RemoteDecodeHelper
{
    static int webclienttimeout = 30 * 1000;
    static Process p = new Process();
    static string serverhost = "http://127.0.0.1:58137/";
    public static List<CodeInfo> DecodeRequest(HObject hoimg, RemoteDecodeParam remoteDecodeParam)
    {
        byte[] requestdata;
        lock (hoimg)
        {
            using (MemoryStream mStream = new MemoryStream())
            {
                hoimg.Serialize(mStream);
                requestdata = mStream.ToArray();
                mStream.Close();
            }
        }
        return DecodeRequest(requestdata, remoteDecodeParam,true);
    }
    public static List<CodeInfo> DecodeRequest(Bitmap bitmap, RemoteDecodeParam remoteDecodeParam)
    {
        if (bitmap == null)
            return null;
        byte[] requestdata;
        lock (bitmap)
        {
            using (MemoryStream mStream = new MemoryStream())
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(mStream, bitmap);
                requestdata = mStream.ToArray();
                mStream.Close();
            }
        }
        return DecodeRequest(requestdata, remoteDecodeParam);
    }
    static List<CodeInfo> DecodeRequest(byte[] requestdata, RemoteDecodeParam remoteDecodeParam,bool isHObject=false)
    {
        try
        {
            CheckAndRunServer();
        }
        catch (Exception ex) { 
            return new List<CodeInfo> { new CodeInfo("ScanCodeServer start error:"+ ex, 0,0) };
        }
        string param;
        using (MemoryStream mStreamparam = new MemoryStream())
        {
            XmlSerializer xf = new XmlSerializer(typeof(RemoteDecodeParam));
            xf.Serialize(mStreamparam, remoteDecodeParam);
            param = base64UrlEncode(mStreamparam.ToArray());
            mStreamparam.Close();
        }
        string url = serverhost+"ProcessBitmap?param=";
        if (isHObject)
            url = serverhost+"Process?param=";
        byte[] resp;
        try
        {
            using (MyWebClient webClient = new MyWebClient(webclienttimeout))
            {
                resp = webClient.UploadData(url + param, requestdata);
                requestdata = null;
            }
        }
        catch(WebException we)
        {
            TaskKill("ScanCodeServer");
            return new List<CodeInfo> { new CodeInfo("ScanCodeServer run error:" + we, 0, 0) };
        }
        catch
        {
            return null;
        }

        List<CodeInfo> codeInfos=null;
        var ss = Encoding.UTF8.GetString(resp).Trim().Trim('"');
        ss = ss.Replace(@"\/", "/");
        try
        {
            var bb = Convert.FromBase64String(ss);
            
            using (MemoryStream mStreamResult = new MemoryStream(bb))
            {
                XmlSerializer xff = new XmlSerializer(typeof(List<CodeInfo>));
                codeInfos = (List<CodeInfo>)xff.Deserialize(mStreamResult);
            }
        }
        catch {
            throw new Exception(ss);
        }
        return codeInfos;
    }

    /// <summary>
    /// 在url中传递base64字符串需要替换加号等符号
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    static string base64UrlEncode(byte[] input)
    {
        return Convert.ToBase64String(input).Replace('+', '-').Replace('/', '_');
    }
    /// <summary>
    /// 检查并自动启动服务器
    /// </summary>
    static void CheckAndRunServer()
    {
        lock (p)
        {
            var port = (int)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\ScanCodeServer\\", "port", 58137);
            serverhost = "http://127.0.0.1:" + port + "/";
            var pss = Process.GetProcessesByName("ScanCodeServer");
            if (pss.Length > 0 && !pss[0].HasExited)
                return;

            var f = Application.StartupPath+ "\\ScanCodeServer\\ScanCodeServer.exe";
            if (!File.Exists(f))
            {
                throw new Exception("找不到扫码服务器文件");
            }
            p.StartInfo = new ProcessStartInfo(f);
            p.Start();
            Thread.Sleep(3000);
            int checkcount = 15;
            while (checkcount > 0)
            {
                checkcount--;
                Thread.Sleep(500);
                port = (int)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\ScanCodeServer\\", "port", 58137);
                serverhost = "http://127.0.0.1:"+ port + "/";
                using (MyWebClient webClient = new MyWebClient(webclienttimeout))
                {
                    var s = webClient.DownloadString(serverhost + "alive");
                    if (s.Trim() == "\"1\"")
                        return;
                }
            }
            TaskKill("ScanCodeServer");
            throw new Exception("扫码服务器打开失败,退出码:"+ p.ExitCode);
        }
    }
    static void TaskKill(string processname) {
        var pss = Process.GetProcessesByName(processname);
        foreach (var p in pss)
        {
            try
            {
                p.Kill();
            }
            catch { }
        }
    }

    [Serializable]
    public struct RemoteDecodeParam
    {
        public string[] codeTypeList;
        public int codeCount;
        public int timeout;
    }

    public class MyWebClient : WebClient
    {
        private int _timeout;
        public MyWebClient(int timeout)
        {
            this._timeout = timeout;
        }
        protected override WebRequest GetWebRequest(Uri address)
        {
            var result = base.GetWebRequest(address);
            result.Timeout = this._timeout;
            return result;
        }
    }

}