using System;
using System.Collections;
using System.Collections.Generic;
using static System.Configuration.ConfigurationManager;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Web;
using System.Web.Services;
using Microsoft.AspNet.SignalR;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using static Newtonsoft.Json.JsonConvert;
using static iMESCore.Base.iMESConst;
using static iMESCore.Base.iMESComXML;
using static iMESCore.Base.iMESComSubroutine;
using System.Xml;
using System.Text;
using System.Linq;
using Microsoft.VisualBasic.ApplicationServices;

namespace MESws
{

    [WebService(Namespace = "http://www.imestech.com/wsInvoke")]
    [System.Web.Script.Services.ScriptService()]
    public class wsInvoke : WebService
    {

        private System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();       // 用以讀取Xml字串
        private string strIdentity;
        private string strReturnValue;            // ReturnValue XML字串
        private string strException;              // Exception XML字串
        private string strResult;                 // Result XML字串
        private iMESCore.Settings.AppSettings objSetting = new iMESCore.Settings.AppSettings();
        private string strResourceDir = "Resources";

        public wsInvoke()
        {
            try
            {
                strResourceDir = System.IO.Path.Combine("wsUpdateResource", objSetting["ResourceDir"].ToString());
            }
            catch (Exception)
            { }
        }

        /// <summary>
        /// 叫用Web Service
        /// 2019/06/20 Lena, Mantis: 0058845 [WIP] CI/CO執行時間紀錄
        /// 調整為 parameters 會多傳入一個 LogOn 參數(True/False),在 Arrary 的最後一個.
        /// 2019/08/27 OwenLiu, Mantis:0061520, 修正invokeSrv啟用CI/CO 效能監控 與之前版本不相容問題
        /// </summary>
        /// <param name="method">要呼叫哪一個WebService的方法, ex: wsWIP.LoadLotBasis</param>
        /// <param name="parameters">要傳入method的參數</param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke with objects and Return XML")]
        public object invokeSrv(string method, object[] parameters)
        {

            object result;

            result = Invoke(method, ref parameters);
            return result;

        }

        /// <summary>
        /// 2019/08/27 OwenLiu, Mantis:0061520, 修正invokeSrv啟用CI/CO 效能監控 與之前版本不相容問題
        /// </summary>
        /// <param name="method"></param>
        /// <param name="parameters"></param>
        /// <param name="LogOn"></param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke with objects and Return XML, And Enable Performance Log")]
        public object invokeSrv_EnableLog(string method, object[] parameters, bool LogOn)
        {

            object result;

            if (LogOn)
            {
                result = Invoke(method, ref parameters, LogOn);
            }
            else
            {
                result = Invoke(method, ref parameters);
            }

            return result;

        }

        /// <summary>
        /// 透過傳入的InXml, 叫用Web Service
        /// </summary>
        /// <param name="method">要呼叫哪一個WebService的方法, ex: wsWIP.LoadLotBasis</param>
        /// <param name="inXMl">要傳入method的Xml</param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke with Xml String and Return XML")]
        public object invokeSrv_Xml(string method, string inXMl)
        {
            var argparameters = new object[] { inXMl };
            var result = Invoke(method, ref argparameters);
            return result;
        }

        /// <summary>
        /// 透過傳入的InXml, 叫用Web Service, 並同時啟用Session
        /// </summary>
        /// <param name="method">要呼叫哪一個WebService的方法, ex: wsWIP.LoadLotBasis</param>
        /// <param name="inXMl">要傳入method的Xml</param>
        /// <returns></returns>
        [WebMethod(Description = "EnableSession, Invoke with Xml String and Return XML", EnableSession = true)]
        public object invokeSrv_Xml_Session(string method, string inXMl)
        {
            var argparameters = new object[] { inXMl };
            var result = Invoke(method, ref argparameters);
            return result;
        }

        /// <summary>
        /// 叫用Web Service
        /// </summary>
        /// <param name="method">要呼叫哪一個WebService的方法, ex: wsWIP.LoadLotBasis</param>
        /// <param name="parameters">要傳入method的參數</param>
        /// <param name="pDataTable">要傳入method的參數</param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke with DataTable and Object Return XML")]
        public object invokeSrv_DataTableParameter(string method, object[] parameters, ref DataTable pDataTable)
        {
            parameters.SetValue(pDataTable, parameters.Length - 1);
            var result = Invoke(method, ref parameters);
            pDataTable = (DataTable)parameters[parameters.Length - 1];
            return result;
        }

        /// <summary>
        /// 叫用Web Service
        /// </summary>
        /// <param name="method">要呼叫哪一個WebService的方法, ex: wsWIP.LoadLotBasis</param>
        /// <param name="InXml">InXml</param>
        /// <param name="pDataTable">接收結果的DataTable</param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke with DataTable and Return XML")]
        public object invokeSrv_DataTable(string method, string InXml, ref DataTable pDataTable)
        {
            object[] parameters = new object[] { InXml, pDataTable };
            var result = Invoke(method, ref parameters);
            pDataTable = (DataTable)parameters[1];
            return result;
        }

        /// <summary>
        /// 叫用Web Service
        /// </summary>
        /// <param name="method">要呼叫哪一個WebService的方法, ex: wsWIP.LoadLotBasis</param>
        /// <param name="InXml">InXml</param>
        /// <param name="pDataSet">接收結果的DataSet</param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke with DataSet and Return XML")]
        public object invokeSrv_DataSet(string method, string InXml, ref DataSet pDataSet)
        {
            object[] parameters = new object[] { InXml, pDataSet };
            var result = Invoke(method, ref parameters);
            pDataSet = (DataSet)parameters[1];

            // 2016-08-29, Joe, 因MESSeries.exe一開啟程式會將CultureInfo改成en-US，如ws沒有將Culture同步調整會造成DataTable Relation時造成Locale不同而錯誤
            var ciCultureInfo = new System.Globalization.CultureInfo("en-US");
            foreach (DataTable dt in pDataSet.Tables)
                dt.Locale = ciCultureInfo;

            return result;
        }

        /// <summary>
        /// 叫用Web Service
        /// </summary>
        /// <param name="method">Web Service的方法</param>
        /// <param name="parameters">參數</param>
        /// <returns></returns>
        [WebMethod(Description = "EnableSession, Invoke and Return XML", EnableSession = true)]
        public object invokeSrv_Session(string method, object[] parameters)
        {
            var result = Invoke(method, ref parameters);
            return result;
        }

        // 前端傳入範例(metadata)
        // {
        // "computername": "H-08453-1",
        // "curuserno": "IMES",
        // "sendtime": "2019/02/13 14:02:59",
        // "languagemode": "zh-cht",
        // "method": "wsUSR.ChkUserSecurity_json"
        // }

        // 前端傳入範例(content)
        // {
        // "userno": "1",
        // "computername": "H-08453-1",
        // "clearcodepassword": "1"
        // }
        /// <summary>
        /// 2019/02/13 OwenLiu, 標準版WS增加 InvokeSrv_Session_json共用函式，供User登入之用
        /// </summary>
        /// <param name="metadata"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        [WebMethod(Description = "EnableSession, Invoke Web Service Resolved json", EnableSession = true)]
        public string invokeSrv_Session_json(string metadata, string parameter)
        {

            var result = default(object);
            string strResponse = "";
            string strMessage = "";
            string method = "";
            string strClassName = "";
            string strMethodName = "";
            string strComponent = "";
            string[] aryTemp;
            string typeName;
            Type t;
            MethodInfo mi;
            Type[] argumentTypes;
            ConstructorInfo ctor;
            object obj;
            string strSendTime = "";
            var ometadata = new Dictionary<string, string>();
            var oResponseMsg = new iMES_ResponseMessage();

            do
            {
                try
                {
                    if (metadata == null || string.IsNullOrEmpty(metadata.Trim()) || string.IsNullOrEmpty(metadata))
                    {
                        break;
                    }
                    // If (parameter Is Nothing) OrElse (parameter.Trim = "") OrElse (String.IsNullOrEmpty(parameter)) Then
                    // Exit Try
                    // End If

                    DateTime argobjSource = DateTime.Now;
                    strSendTime = funTransVarFormat(argobjSource, "yyyy/MM/dd HH:mm:ss");

                    ometadata = DeserializeObject<Dictionary<string, string>>(metadata);

                    if (!ometadata.ContainsKey("method"))
                        break;
                    method = ometadata["method"];
                    aryTemp = method.Split('.');

                    if (aryTemp.Length < 2 || aryTemp.Length > 3)
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    if (aryTemp.Length == 2)
                    {
                        strComponent = "wsSTD.dll";
                        strClassName = aryTemp[0];
                        strMethodName = aryTemp[1];
                    }
                    else if (aryTemp.Length == 3 && aryTemp[1].StartsWith("ws") == false)  // 2017-06-09, Joe, 不透過ws直接Call kc/tc/ud
                    {
                        // 前端傳入：kcXXX.clsXXX.AddXXXXX
                        strComponent = aryTemp[0] + ".dll";   // dll name
                        strClassName = aryTemp[1];   // class name
                        strMethodName = aryTemp[2];  // function name
                    }
                    else
                    {
                        strComponent = "ws" + aryTemp[0] + ".dll";
                        strClassName = aryTemp[1];
                        strMethodName = aryTemp[2];
                    }

                    if (string.IsNullOrEmpty(strComponent) || string.IsNullOrEmpty(strClassName) || string.IsNullOrEmpty(strMethodName))
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    string strAppBase = AppDomain.CurrentDomain.BaseDirectory;
                    string strFilePath = strAppBase.TrimEnd('\\') + @"\bin\" + strComponent;
                    var mainAssembly = Assembly.LoadFrom(strFilePath);

                    try
                    {
                        t = mainAssembly.GetType(mainAssembly.GetName().Name + "." + strClassName, true, true);
                    }
                    catch (Exception ex)
                    {
                        throw new iMESException.MESException("0000-003000", "WebService: " + strClassName + " [%LOAD FAIL%]!" + Constants.vbCrLf + ex.Message);
                    }

                    argumentTypes = Type.EmptyTypes;
                    ctor = t.GetConstructor(argumentTypes);
                    obj = ctor.Invoke(new object[] { });
                    mi = t.GetMethod(strMethodName);

                    try
                    {
                        result = mi.Invoke(obj, new object[] { metadata, parameter });
                    }
                    catch (Exception ex)
                    {
                        if (ex.InnerException == null)
                        {
                            strMessage = ex.Message;
                        }
                        else
                        {
                            strMessage = ex.InnerException.Message;
                        }
                        throw new iMESException.MESException("0000-003000", strClassName + "." + strMethodName + " [%INVOKE FAIL%]!" + Constants.vbCrLf + strMessage);
                    }
                }

                catch (iMESException.MESException ex)
                {
                    if (ex.InnerException == null)
                    {
                        oResponseMsg.code = Convert.ToString(ex.ErrorCode);
                        oResponseMsg.exception = "invokeSrv_Session_json fail;" + ex.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    else
                    {
                        oResponseMsg.code = Convert.ToString(ex.ErrorCode);
                        oResponseMsg.exception = "invokeSrv_Session_json fail;" + ex.InnerException.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    result = oResponseMsg.CombineRsponseMessage(oResponseMsg, ometadata["languagemode"], strResourceDir);
                }
                catch (Exception ex)
                {
                    if (ex.InnerException == null)
                    {
                        oResponseMsg.code = defWSErrCode;
                        oResponseMsg.exception = "invokeSrv_Session_json fail;" + ex.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    else
                    {
                        oResponseMsg.code = defWSErrCode;
                        oResponseMsg.exception = "invokeSrv_Session_json fail;" + ex.InnerException.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    result = oResponseMsg.CombineRsponseMessage(oResponseMsg, ometadata["languagemode"], strResourceDir);
                }
                finally
                {

                    oResponseMsg = null;
                }
            }
            while (false);

            return Convert.ToString(result);

        }

        /// <summary>
        /// 2020/03/23 Yenru, 新增將DataTable 轉為Json格式資料查訊接口
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke Web Service Resolved json")]
        public string invokeSrv_iMES_json(string uri, string content)
        {

            var result = default(object);
            string strResponse = "";
            string strMessage = "";
            string method = "";
            string strClassName = "";
            string strMethodName = "";
            string strComponent = "";
            string[] aryTemp;
            string typeName;
            Type t;
            MethodInfo mi;
            Type[] argumentTypes;
            ConstructorInfo ctor;
            object obj;
            string strSendTime = "";
            var ometadata = new Dictionary<string, string>();
            var oResponseMsg = new iMES_ResponseMessage();

            do
            {
                try
                {
                    if (uri == null || string.IsNullOrEmpty(uri.Trim()) || string.IsNullOrEmpty(uri))
                    {
                        break;
                    }

                    object argobjSource = DateTime.Now;
                    strSendTime = funTransVarFormat(argobjSource, "yyyy/MM/dd HH:mm:ss");

                    ometadata = DeserializeObject<Dictionary<string, string>>(uri);

                    if (!ometadata.ContainsKey("method"))
                        break;
                    method = ometadata["method"];
                    aryTemp = method.Split('.');

                    if (aryTemp.Length == 1)
                    {
                        // STD
                        strComponent = "wsSTD.dll";
                        strClassName = "wsMDS";
                        strMethodName = aryTemp[0];
                    }
                    else if (aryTemp.Length == 2)
                    {
                        // CUS
                        strComponent = aryTemp[0] + ".dll";   // dll name
                        strClassName = aryTemp[1];   // class name
                        strMethodName = aryTemp[2];  // function name
                    }

                    if (string.IsNullOrEmpty(strComponent) || string.IsNullOrEmpty(strClassName) || string.IsNullOrEmpty(strMethodName))
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    string strAppBase = AppDomain.CurrentDomain.BaseDirectory;
                    string strFilePath = strAppBase.TrimEnd('\\') + @"\bin\" + strComponent;
                    var mainAssembly = Assembly.LoadFrom(strFilePath);

                    try
                    {
                        t = mainAssembly.GetType(mainAssembly.GetName().Name + "." + strClassName, true, true);
                    }
                    catch (Exception ex)
                    {
                        throw new iMESException.MESException("0000-003000", "WebService: " + strClassName + " [%LOAD FAIL%]!" + Constants.vbCrLf + ex.Message);
                    }

                    argumentTypes = Type.EmptyTypes;
                    ctor = t.GetConstructor(argumentTypes);
                    obj = ctor.Invoke(new object[] { });
                    mi = t.GetMethod(strMethodName);

                    try
                    {
                        result = mi.Invoke(obj, new object[] { content });
                    }
                    catch (Exception ex)
                    {
                        if (ex.InnerException == null)
                        {
                            strMessage = ex.Message;
                        }
                        else
                        {
                            strMessage = ex.InnerException.Message;
                        }
                        throw new iMESException.MESException("0000-003000", strClassName + "." + strMethodName + " [%INVOKE FAIL%]!" + Constants.vbCrLf + strMessage);
                    }
                }

                catch (iMESException.MESException ex)
                {
                    if (ex.InnerException == null)
                    {
                        oResponseMsg.code = Convert.ToString(ex.ErrorCode);
                        oResponseMsg.exception = "invokeSrv_json fail;" + ex.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    else
                    {
                        oResponseMsg.code = Convert.ToString(ex.ErrorCode);
                        oResponseMsg.exception = "invokeSrv_json fail;" + ex.InnerException.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    result = oResponseMsg.CombineRsponseMessage(oResponseMsg, ometadata["languagemode"], strResourceDir);
                }
                catch (Exception ex)
                {
                    if (ex.InnerException == null)
                    {
                        oResponseMsg.code = defWSErrCode;
                        oResponseMsg.exception = "invokeSrv_json fail;" + ex.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    else
                    {
                        oResponseMsg.code = defWSErrCode;
                        oResponseMsg.exception = "invokeSrv_json fail;" + ex.InnerException.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    result = oResponseMsg.CombineRsponseMessage(oResponseMsg, ometadata["languagemode"], strResourceDir);
                }
                finally
                {

                    oResponseMsg = null;
                }
            }
            while (false);

            return Convert.ToString(result);

        }

        /// <summary>
        /// 叫用Web Service的方法
        /// </summary>
        /// <param name="method">Web Service的方法</param>
        /// <param name="parameters">參數</param>
        /// <returns>
        /// 2016/06/22 YF, 調整Invoke以符合產業包叫用方式
        ///     標準版呼叫方式: invokeSrv("wsENT.AddCustomerBasis", InXml)
        ///     產業包呼叫方式: invokeSrv("LED.wsWIP.Exe_CheckOut_Sorter", InXml)
        ///     以小數點劃分, 小數點有兩位為標準版wsSTD, 小數點有三位為產業包(第1位為產業代號, 本例為wsLED)
        /// 2019/06/20 Lena, Mantis: 0058845 [WIP] CI/CO 執行時間紀錄  
        /// </returns>
        private object Invoke(string method, ref object[] parameters, bool LogOn = false)
        {

            object result;
            string[] aryTemp;
            string strClassName = "";
            string strMethodName = "";
            string typeName;
            Type t;
            Type[] argumentTypes;
            ConstructorInfo ctor;
            object obj;
            MethodInfo mi;
            string strMessage;
            var strComponent = default(string);

            DateTime datStartTime = default(DateTime), datEndTime;
            var stpCostTime = new Stopwatch();
            short intParameterLength = 0;

            try
            {


                // 2019/06/20 Lena, Mantis: 0058845
                // 記錄執行開始時間.
                stpCostTime.Start();
                datStartTime = DateTime.Now;

                string argComputerName = Server.MachineName;
                string argCurUserNo = Server.MachineName;
                string argSendTime = Strings.Format(DateTime.Now, "yyyy/MM/dd HH:mm:ss");
                strIdentity = CombineXMLIdentity(argComputerName, argCurUserNo, argSendTime);

                // 取出Class及Method
                if (string.IsNullOrEmpty(method.Trim()))
                {
                    throw new iMESException.MESException("0000-003000", "Invoke method [%IS EMPTY%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis!");
                }

                aryTemp = method.Split('.');

                if (aryTemp.Length < 2 || aryTemp.Length > 3)
                {
                    throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                }

                if (aryTemp.Length == 2)
                {
                    strComponent = "wsSTD.dll";
                    strClassName = aryTemp[0];
                    strMethodName = aryTemp[1];
                }
                else if (aryTemp.Length == 3 && aryTemp[1].StartsWith("ws") == false)  // 2017-06-09, Joe, 不透過ws直接Call kc/tc/ud
                {
                    // 前端傳入：kcXXX.clsXXX.AddXXXXX
                    strComponent = aryTemp[0] + ".dll";   // dll name
                    strClassName = aryTemp[1];   // class name
                    strMethodName = aryTemp[2];  // function name
                }
                else
                {
                    strComponent = "ws" + aryTemp[0] + ".dll";
                    strClassName = aryTemp[1];
                    strMethodName = aryTemp[2];
                }

                if (string.IsNullOrEmpty(strComponent) || string.IsNullOrEmpty(strClassName) || string.IsNullOrEmpty(strMethodName))
                {
                    throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                }

                string strAppBase = AppDomain.CurrentDomain.BaseDirectory;
                string strFilePath = strAppBase.TrimEnd('\\') + @"\bin\" + strComponent;
                var mainAssembly = Assembly.LoadFrom(strFilePath);

                try
                {
                    t = mainAssembly.GetType(mainAssembly.GetName().Name + "." + strClassName, true, true);
                }
                catch (Exception ex)
                {
                    throw new iMESException.MESException("0000-003000", "WebService: " + strClassName + " [%LOAD FAIL%]!" + Constants.vbCrLf + ex.Message);
                }

                argumentTypes = Type.EmptyTypes;
                ctor = t.GetConstructor(argumentTypes);
                obj = ctor.Invoke(new object[] { });
                mi = t.GetMethod(strMethodName);

                try
                {
                    // 2019/08/27 OwenLiu, Mantis:0061520, 修正invokeSrv啟用CI/CO 效能監控 與之前版本不相容問題
                    intParameterLength = (short)mi.GetParameters().GetLength(0);

                    if (parameters != null && parameters.Length > 0)
                    {

                        // 0106799: [共用程式]新增XML格式合理性查核
                        ParameterInfo[] aryParameterInfo = mi.GetParameters();
                        for (int i = 0, loopTo = aryParameterInfo.Length - 1; i <= loopTo; i++)
                        {
                            if (aryParameterInfo[i].Name.ToUpper().Contains("INXML"))
                            {
                                string strInXML = "";
                                strInXML = parameters[i].ToString();
                                if (!string.IsNullOrEmpty(strInXML))
                                {
                                    if (!CheckXML(strInXML))
                                    {
                                        // 「傳入XML無法被正確解析，因包含特殊符号或格式不相符」
                                        throw new iMESException.MESException("0000-003000", "[%XML Cannot Be Parsed Correctly,Because of Special Symbols%]");
                                    }
                                }
                                break;
                            }
                        }

                        string strBooleanValueTemp = "";
                        if (intParameterLength < parameters.Length && IsBoolean(parameters[parameters.Length - 1].ToString(), ref strBooleanValueTemp))
                        {
                            var subParameters = new object[intParameterLength];
                            Array.Copy(parameters, subParameters, intParameterLength);
                            result = mi.Invoke(obj, subParameters);
                        }
                        else
                        {
                            result = mi.Invoke(obj, parameters);
                        }
                    }
                    else
                    {
                        result = mi.Invoke(obj, parameters);
                    }
                }



                catch (Exception ex)
                {
                    if (ex.InnerException == null)
                    {
                        strMessage = ex.Message;
                    }
                    else
                    {
                        strMessage = ex.InnerException.Message;
                    }
                    throw new iMESException.MESException("0000-003000", strClassName + "." + strMethodName + " [%INVOKE FAIL%]!" + Constants.vbCrLf + strMessage);
                }
            }

            catch (iMESException.MESException ex)
            {
                if (ex.InnerException == null)
                {
                    string argcode = Convert.ToString(ex.ErrorCode);
                    string argsysmsg = ex.Message;
                    string argmesmsg = "Invoke Fail!";
                    strException = CombineXMLException(argcode, argsysmsg, argmesmsg, ex.StackTrace);
                }
                else
                {
                    string argcode1 = Convert.ToString(ex.ErrorCode);
                    string argsysmsg1 = ex.InnerException.Message;
                    string argmesmsg1 = "Invoke Fail!";
                    strException = CombineXMLException(argcode1, argsysmsg1, argmesmsg1, ex.StackTrace);
                }
                string argReturnValue = "";
                string argResult = "fail";
                string argMessage = "";
                result = CombineXMLResponse(strIdentity, argReturnValue, strException, argResult, argMessage);
            }
            catch (Exception ex)
            {
                if (ex.InnerException == null)
                {
                    string argsysmsg = ex.Message;
                    string argmesmsg = "Invoke Fail!";
                    strException = CombineXMLException(defWSErrCode, argsysmsg, argmesmsg, ex.StackTrace);
                }
                else
                {
                    string argsysmsg1 = ex.InnerException.Message;
                    string argmesmsg1 = "Invoke Fail!";
                    strException = CombineXMLException(defWSErrCode, argsysmsg1, argmesmsg1, ex.StackTrace);
                }
                string argReturnValue = "";
                string argResult = "fail";
                string argMessage = "";
                result = CombineXMLResponse(strIdentity, argReturnValue, strException, argResult, argMessage);
            }

            // 2020/07/06 雋辰,Info Log
            string strParameterMsg = "";
            try
            {
                if (!(parameters == null))
                {
                    foreach (object item in parameters)
                    {
                        if (item == null)
                        {
                            strParameterMsg += "parameter is Null" + Constants.vbNewLine;
                        }
                        else
                        {
                            strParameterMsg += item.ToString() + Constants.vbNewLine;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                strParameterMsg = ex.ToString();
            }
            try
            {
                var strBulder = new System.Text.StringBuilder();
                strBulder.AppendLine("Method:" + method);
                strBulder.AppendLine("Parameter:");
                strBulder.Append(strParameterMsg);
                if (result == null)
                {
                    strBulder.Append("Response:" + "");
                }
                else
                {
                    strBulder.Append("Response:" + result.ToString());
                }
                Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Info, null);
            }
            catch (Exception ex)
            {
                Log.WriteLog("WriteLog Info fail:" + method, iMESLog.iMESLogLevel.Warn, ex);
            }

            // 2020/06/30 雋辰,新增Nlog相關
            if (!(result == null || result.ToString() == ""))
            {
                try
                {
                    var XmlDoc = new System.Xml.XmlDocument();
                    if (result == null)
                    {
                        XmlDoc.LoadXml("");
                    }
                    else
                    {
                        XmlDoc.LoadXml(result.ToString());
                    }

                    if (!chkExecutionSuccess(XmlDoc))
                    {
                        string exCode = GetExceptionCode(XmlDoc);
                        string exMsg = GetExceptionSysMsg(XmlDoc);
                        string exStack = GetExceptionStack(XmlDoc);
                        var strBulder = new System.Text.StringBuilder();
                        strBulder.AppendLine("Method:" + method);
                        strBulder.AppendLine("Code:" + exCode);
                        strBulder.AppendLine("Msg:" + exMsg);
                        strBulder.AppendLine("Parameter:");
                        strBulder.Append(strParameterMsg);
                        strBulder.Append("Stack:" + exStack);
                        Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Error, null);
                    }
                }
                catch (System.Xml.XmlException exXML)
                {
                    try
                    {
                        // 2020/0810 雋辰,可能有Response是Json格式
                        iMESCIO.CDO.Common.RsponseMessage response;
                        if (result == null)
                        {
                            response = DeserializeObject<iMESCIO.CDO.Common.RsponseMessage>("");
                        }
                        else
                        {
                            response = DeserializeObject<iMESCIO.CDO.Common.RsponseMessage>(result.ToString().Replace(@"\\", ""));
                        }
                        if (response.Code != "0")
                        {
                            var strBulder = new System.Text.StringBuilder();
                            strBulder.AppendLine("Method:" + method);
                            strBulder.AppendLine("Code:" + response.Code);
                            strBulder.AppendLine("CodeInformation:" + response.CodeInformation);
                            strBulder.AppendLine("Msg:" + response.Message);
                            strBulder.AppendLine("Parameter:");
                            strBulder.Append(strParameterMsg);
                            strBulder.Append("Stack:" + response.StackTrace);
                            Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Error, null);
                        }
                    }
                    catch (Exception ex)
                    {
                        var strBulder = new System.Text.StringBuilder();
                        strBulder.AppendLine("WriteLog Err fail:");
                        strBulder.AppendLine("Method:" + method);
                        if (result == null)
                        {
                            strBulder.Append("Response:" + "");
                        }
                        else
                        {
                            strBulder.Append("Response:" + result.ToString().Replace(@"\\", ""));
                        }
                        Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Warn, ex);
                    }
                }
                catch (Exception ex)
                {
                    var strBulder = new System.Text.StringBuilder();
                    strBulder.AppendLine("WriteLog Err fail:");
                    strBulder.AppendLine("Method:" + method);
                    if (result == null)
                    {
                        strBulder.Append("Response:" + "");
                    }
                    else
                    {
                        strBulder.Append("Response:" + result.ToString().Replace(@"\\", ""));
                    }
                    Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Warn, ex);
                }
            }

            // 2019/06/20 Lena, Mantis: 0058845
            // 記錄執行結束時間.
            stpCostTime.Stop();
            datEndTime = DateTime.Now;

            // 79915:  效能監控擴充 2020/10/20 效能監控 Edison
            // ==============================================79915 Start ==============================================
            // If LogOn Then
            if (!string.IsNullOrEmpty(strComponent) && !string.IsNullOrEmpty(strClassName) && !string.IsNullOrEmpty(strMethodName))
            {
                // ==============================================79915  End  ==============================================

                long Duration = 0L;
                string InXml;
                string UserNo = "N/A";
                string ComputerName = "N/A";
                string LotNo = "N/A";

                var XmlDoc = new System.Xml.XmlDocument();

                try
                {

                    // 取出開始到結束的執行時間(毫秒為單位).
                    Duration = stpCostTime.ElapsedMilliseconds;

                    // 取出 InXml
                    // 2019/08/27 OwenLiu, Mantis:0061520, 修正invokeSrv啟用CI/CO 效能監控 與之前版本不相容問題
                    if (parameters != null && parameters.Length > 0)
                    {

                        string strBooleanValueTmp = "";
                        if (intParameterLength < parameters.Length && IsBoolean(parameters[parameters.Length - 1].ToString(), ref strBooleanValueTmp))
                        {
                            InXml = parameters[parameters.Length - 2].ToString();
                            // 讀取 InXml字串
                            XmlDoc.LoadXml(InXml);
                            // 取出 UserNo,ComputerName
                            UserNo = GetXMLCurUserNo(XmlDoc);
                            ComputerName = GetXMLCurComputer(XmlDoc);

                            if (XmlDoc.DocumentElement.GetElementsByTagName("lotno").Count > 0)
                            {
                                if (XmlDoc.GetElementsByTagName("lotno").Item(0).SelectNodes("value").Count > 0)
                                {
                                    LotNo = XmlDoc.DocumentElement.GetElementsByTagName("lotno").Item(0).SelectNodes("value").Item(0).InnerText;
                                }
                            }
                        }
                        else
                        {
                            InXml = parameters[parameters.Length - 1].ToString();
                            // 讀取 InXml字串
                            XmlDoc.LoadXml(InXml);
                            // 取出 UserNo,ComputerName
                            UserNo = GetXMLCurUserNo(XmlDoc);
                            ComputerName = GetXMLCurComputer(XmlDoc);

                            if (XmlDoc.DocumentElement.GetElementsByTagName("lotno").Count > 0)
                            {
                                if (XmlDoc.GetElementsByTagName("lotno").Item(0).SelectNodes("value").Count > 0)
                                {
                                    LotNo = XmlDoc.DocumentElement.GetElementsByTagName("lotno").Item(0).SelectNodes("value").Item(0).InnerText;
                                }
                            }
                        }
                    }
                }

                catch (Exception ex)
                {
                }

                finally
                {
                    XmlDoc = null;
                }

                // 79915:  效能監控擴充 2020/10/20 效能監控 Edison
                // ==============================================79915 Start ==============================================
                int intChkDurationLog = -1;

                using (var objSYS = new kcSYS.clsSYSUserLog())
                {
                    try
                    {
                        intChkDurationLog = objSYS.ChkDurationLog(strComponent, strClassName, strMethodName);
                    }
                    catch (Exception ex)
                    {
                        objSYS.AddErrorLog("wsInvoke.Invoke", UserNo, "ChkDurationLog", method, datEndTime, ex.Message, ComputerName: ComputerName);
                    }

                    // 2020/05/18 Shih Kai, 71364: 若寫入失敗，則新增一筆 ErrorLog 
                    // 記錄Log
                    if (intChkDurationLog == 0)
                    {
                        try
                        {
                            // 2022/6/6,Ning,記錄LotNo
                            if (LotNo != "N/A")
                            {
                                strMethodName = strMethodName + ", LotNo: " + LotNo;
                            }
                            objSYS.AddMESTransactionLog(UserNo, strComponent, strClassName, strMethodName, datStartTime, datEndTime, Duration, ComputerName);
                        }
                        catch (Exception ex)
                        {
                            objSYS.AddErrorLog("wsInvoke.Invoke", UserNo, "AddMESTransactionLog", method, datEndTime, ex.Message, ComputerName: ComputerName);
                        }
                    }

                }
                // ==============================================79915  End  ==============================================

            }

            return result;

        }


        // 2016/07/05 YF
        [WebMethod(Description = "Web service and database connection test")]
        public string Test(string UserNo)
        {
            string TestRet = default(string);

            try
            {
                // 呼叫Dll執行
                using (var obj = new iMESUserManager.clsUSRSecurity())
                {
                    TestRet = obj.Test(UserNo);
                }
            }

            catch (Exception ex)
            {
                string argsysmsg = ex.Message;
                string argmesmsg = "Test failed!";
                TestRet = CombineXMLException(defWSErrCode, argsysmsg, argmesmsg, ex.StackTrace);
            }

            return TestRet;

        }

        [WebMethod(Description = "Web service connection test")]
        public string Testalive(string request)
        {
            string strTransactionId = "", strModuleId = "", strComputerName = "",
               strCuruserNo = "", strSendTime = "", strLanguageMode = "", strState = "";

            try
            {
                var XmlDoc = new System.Xml.XmlDocument();

                try
                {
                    XmlDoc.LoadXml(request);

                }
                catch (Exception e)
                {
                    throw new iMESException.MESException("0000-003000", "[%ABNORMAL INTERFACE FORMAT%]");
                }

                var rowNoteList = XmlDoc.SelectNodes("/request/identity/*");
                if (rowNoteList != null)
                    foreach (XmlNode rowNode in rowNoteList)
                        switch (rowNode.Name)
                        {
                            case "transactionid":
                                strTransactionId = rowNode.InnerText.Trim();
                                break;

                            case "moduleid":
                                strModuleId = rowNode.InnerText.Trim();
                                break;

                            case "computername":
                                strComputerName = rowNode.InnerText.Trim();
                                break;

                            case "curuserno":
                                strCuruserNo = rowNode.InnerText.Trim();
                                break;

                            case "sendtime":
                                strSendTime = rowNode.InnerText.Trim();
                                break;

                            case "languagemode":
                                strLanguageMode = rowNode.InnerText.Trim();
                                strLanguageMode = strLanguageMode.ToLower();
                                break;
                        }

                var stateNode = XmlDoc.SelectNodes("/request/parameter/state");
                if (stateNode != null)
                    if (stateNode.Count > 0)
                        strState = stateNode[0].InnerText.Trim();

                if (string.IsNullOrEmpty(strTransactionId) || string.IsNullOrEmpty(strModuleId) ||
                    string.IsNullOrEmpty(strComputerName) || string.IsNullOrEmpty(strCuruserNo) ||
                    string.IsNullOrEmpty(strSendTime) || string.IsNullOrEmpty(strLanguageMode) ||
                    string.IsNullOrEmpty(strState))
                {
                    throw new iMESException.MESException("0000-003000", "[%ABNORMAL INTERFACE FORMAT%]");
                }

                return CreateSuccessResponse(strTransactionId, strModuleId, strComputerName, strCuruserNo, strSendTime, strLanguageMode);

            }
            catch (iMESException.MESException e)
            {
                return CreateFailResponse(strTransactionId, strModuleId, strComputerName, strCuruserNo, strSendTime, strLanguageMode,
                    TranslateMsg(e.Message, strLanguageMode, strResourceDir), e.ErrorCode.ToString(), e.StackTrace);

            }
            catch (Exception ex)
            {
                return CreateFailResponse(strTransactionId, strModuleId, strComputerName, strCuruserNo, strSendTime, strLanguageMode,
                    TranslateMsg(ex.Message, strLanguageMode, strResourceDir), defWSErrCode, ex.StackTrace);
            }
        }
        private string CreateFailResponse(string strTransactionId, string strModuleId,
            string strComputerName, string strCuruserNo, string strSendTime, string strLanguageMode,
            string strMesMsg, string strCode, string strStack)
        {
            // 创建XML文档
            var ResposeDoc = new XmlDocument();

            // 创建根节点
            var responseNode = ResposeDoc.CreateElement("response");
            ResposeDoc.AppendChild(responseNode);

            // 创建identity节点
            var identityNode = ResposeDoc.CreateElement("identity");
            responseNode.AppendChild(identityNode);

            // 添加identity子节点
            AddChildNode(ResposeDoc, identityNode, "transactionid", strTransactionId);
            AddChildNode(ResposeDoc, identityNode, "moduleid", strModuleId);
            AddChildNode(ResposeDoc, identityNode, "computername", strComputerName);
            AddChildNode(ResposeDoc, identityNode, "curuserno", strCuruserNo);
            AddChildNode(ResposeDoc, identityNode, "sendtime", strSendTime);
            AddChildNode(ResposeDoc, identityNode, "languagemode", strLanguageMode);

            // 添加其他节点
            AddChildNode(ResposeDoc, responseNode, "returnvalue", "");
            AddChildNode(ResposeDoc, responseNode, "result", "fail");
            AddChildNode(ResposeDoc, responseNode, "message", strMesMsg);

            var exceptionNode = ResposeDoc.CreateElement("exception");
            responseNode.AppendChild(exceptionNode);

            AddChildNode(ResposeDoc, exceptionNode, "code", strCode);
            AddChildNode(ResposeDoc, exceptionNode, "sysmsg", strMesMsg);
            AddChildNode(ResposeDoc, exceptionNode, "mesmsg", strMesMsg);
            AddChildNode(ResposeDoc, exceptionNode, "stack", strStack);

            return ResposeDoc.InnerXml;
        }

        private string CreateSuccessResponse(string strTransactionId, string strModuleId,
            string strComputerName, string strCuruserNo, string strSendTime, string strLanguageMode)
        {
            // 创建XML文档
            var ResposeDoc = new XmlDocument();

            // 创建根节点
            var responseNode = ResposeDoc.CreateElement("response");
            ResposeDoc.AppendChild(responseNode);

            // 创建identity节点
            var identityNode = ResposeDoc.CreateElement("identity");
            responseNode.AppendChild(identityNode);

            // 添加identity子节点
            AddChildNode(ResposeDoc, identityNode, "transactionid", strTransactionId);
            AddChildNode(ResposeDoc, identityNode, "moduleid", strModuleId);
            AddChildNode(ResposeDoc, identityNode, "computername", strComputerName);
            AddChildNode(ResposeDoc, identityNode, "curuserno", strCuruserNo);
            AddChildNode(ResposeDoc, identityNode, "sendtime", strSendTime);
            AddChildNode(ResposeDoc, identityNode, "languagemode", strLanguageMode);

            // 添加其他节点
            AddChildNode(ResposeDoc, responseNode, "returnvalue", "");
            AddChildNode(ResposeDoc, responseNode, "result", "success");
            AddChildNode(ResposeDoc, responseNode, "message",
                TranslateMsg("[%THE SYSTEM IS RUNNING NORMALLY%]", strLanguageMode, strResourceDir));

            return ResposeDoc.InnerXml;
        }
        private void AddChildNode(XmlDocument doc, XmlNode parentNode, string nodeName, string nodeValue)
        {
            var childNode = doc.CreateElement(nodeName);
            childNode.InnerText = nodeValue;
            parentNode.AppendChild(childNode);
        }

        /// <summary>
        /// 呼叫 SignalR
        /// </summary>
        /// <param name="InputString"></param>
        /// <returns></returns>
        [WebMethod(Description = "Call SignalR, Invoke and Return XML")]
        public object invoke_SignalR(string mseContent)
        {
            object invoke_SignalRRet = default(object);

            try
            {
                IHubContext context = GlobalHost.ConnectionManager.GetHubContext<Notification>();
                context.Clients.All.BroadCast(mseContent);
            }
            catch (Exception ex)
            {
                string argsysmsg = ex.Message;
                string argmesmsg = "invoke_SignalR failed!";
                invoke_SignalRRet = CombineXMLException(defWSErrCode, argsysmsg, argmesmsg, ex.StackTrace);
            }

            return invoke_SignalRRet;

        }

        /// 2020/01/15 Shih Kai
        /// <summary>
        /// 後端細切共用轉呼叫函式
        /// </summary>
        /// <param name="method"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke Module with InXml")]
        public object invokeSrv_Module(string method, ref object[] parameters, object pInvokeType, string[] pLogKeyFields, bool blnLogOn)
        {

            object result;
            DataSet argpDataSet = null;
            result = Invoke_Module(ref argpDataSet, method, ref parameters, pInvokeType, pLogKeyFields, blnLogOn);
            return result;

        }

        [WebMethod(Description = "Invoke Module with InXml and DataSet Parameter")]
        public object invokeSrv_Module_DataSet(string method, ref object[] parameters, object pInvokeType, string[] pLogKeyFields, bool blnLogOn, ref DataSet pDataSet)
        {
            object result;
            result = Invoke_Module(ref pDataSet, method, ref parameters, pInvokeType, pLogKeyFields, blnLogOn);
            // 2016-08-29, Joe, 因MESSeries.exe一開啟程式會將CultureInfo改成en-US，如ws沒有將Culture同步調整會造成DataTable Relation時造成Locale不同而錯誤
            var ciCultureInfo = new System.Globalization.CultureInfo("en-US");
            foreach (DataTable dt in pDataSet.Tables)
                dt.Locale = ciCultureInfo;

            return result;
        }

        private object Invoke_Module(ref DataSet pDataSet, string method, ref object[] parameters, object pInvokeType, string[] pLogKeyFields, bool blnLogOn = false)
        {

            object result;
            string[] aryTemp;
            string strClassName = "";
            string strMethodName = "";
            string typeName;
            Type t;
            Type[] argumentTypes;
            ConstructorInfo ctor;
            object obj;
            MethodInfo mi;
            string strMessage;
            var strComponent = default(string);
            short intParameterLength = 0;
            DateTime datStartTime = default(DateTime), datEndTime;
            var stpCostTime = new Stopwatch();

            try
            {

                // 記錄執行開始時間.
                stpCostTime.Start();
                datStartTime = DateTime.Now;

                string argComputerName = Server.MachineName;
                string argCurUserNo = Server.MachineName;
                string argSendTime = Strings.Format(DateTime.Now, "yyyy/MM/dd HH:mm:ss");
                strIdentity = CombineXMLIdentity(argComputerName, argCurUserNo, argSendTime);

                // 取出Class及Method
                if (string.IsNullOrEmpty(method.Trim()))
                {
                    throw new iMESException.MESException("0000-003000", "Invoke method [%IS EMPTY%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis!");
                }

                aryTemp = method.Split('.');

                if (aryTemp.Length < 2 || aryTemp.Length > 3)
                {
                    throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                }

                if (aryTemp.Length == 2)
                {
                    strComponent = "wsSTD.dll";
                    strClassName = aryTemp[0];
                    strMethodName = aryTemp[1];
                }
                else if (aryTemp.Length == 3 && aryTemp[1].StartsWith("ws") == false)  // 2017-06-09, Joe, 不透過ws直接Call kc/tc/ud
                {
                    // 前端傳入：kcXXX.clsXXX.AddXXXXX
                    strComponent = aryTemp[0] + ".dll";   // dll name
                    strClassName = aryTemp[1];   // class name
                    strMethodName = aryTemp[2];  // function name
                }
                else
                {
                    strComponent = "ws" + aryTemp[0] + ".dll";
                    strClassName = aryTemp[1];
                    strMethodName = aryTemp[2];
                }

                if (string.IsNullOrEmpty(strComponent) || string.IsNullOrEmpty(strClassName) || string.IsNullOrEmpty(strMethodName))
                {
                    throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                }

                string strAppBase = AppDomain.CurrentDomain.BaseDirectory;
                string strFilePath = strAppBase.TrimEnd('\\') + @"\bin\" + strComponent;
                var mainAssembly = Assembly.LoadFrom(strFilePath);

                try
                {
                    t = mainAssembly.GetType(mainAssembly.GetName().Name + "." + strClassName, true, true);
                }
                catch (Exception ex)
                {
                    throw new iMESException.MESException("0000-003000", "WebService: " + strClassName + " [%LOAD FAIL%]!" + Constants.vbCrLf + ex.Message);
                }

                argumentTypes = Type.EmptyTypes;
                ctor = t.GetConstructor(argumentTypes);
                obj = ctor.Invoke(new object[] { });
                mi = t.GetMethod(strMethodName);

                try
                {
                    // 解析XML,並Invoke指定Method
                    if (!(pDataSet == null))
                    {
                        result = InvokeFunction_Module((iMESCore.Base._enuInvokeType)pInvokeType, parameters[0].ToString(), ref obj, strMethodName, strComponent, pLogKeyFields, pDataSet);
                    }

                    else
                    {
                        result = InvokeFunction_Module((iMESCore.Base._enuInvokeType)pInvokeType, parameters[0].ToString(), ref obj, strMethodName, strComponent, pLogKeyFields);

                    }
                }

                catch (Exception ex)
                {
                    if (ex.InnerException == null)
                    {
                        strMessage = ex.Message;
                    }
                    else
                    {
                        strMessage = ex.InnerException.Message;
                    }
                    throw new iMESException.MESException("0000-003000", strClassName + "." + strMethodName + " [%INVOKE FAIL%]!" + Constants.vbCrLf + strMessage);
                }
            }

            catch (iMESException.MESException ex)
            {
                if (ex.InnerException == null)
                {
                    string argcode = Convert.ToString(ex.ErrorCode);
                    string argsysmsg = ex.Message;
                    string argmesmsg = "Invoke_Module Fail!";
                    strException = CombineXMLException(argcode, argsysmsg, argmesmsg, ex.StackTrace);
                }
                else
                {
                    string argcode1 = Convert.ToString(ex.ErrorCode);
                    string argsysmsg1 = ex.InnerException.Message;
                    string argmesmsg1 = "Invoke_Module Fail!";
                    strException = CombineXMLException(argcode1, argsysmsg1, argmesmsg1, ex.StackTrace);
                }
                string argReturnValue = "";
                string argResult = "fail";
                string argMessage = "";
                result = CombineXMLResponse(strIdentity, argReturnValue, strException, argResult, argMessage);
            }
            catch (Exception ex)
            {
                if (ex.InnerException == null)
                {
                    string argsysmsg = ex.Message;
                    string argmesmsg = "Invoke_Module Fail!";
                    strException = CombineXMLException(defWSErrCode, argsysmsg, argmesmsg, ex.StackTrace);
                }
                else
                {
                    string argsysmsg1 = ex.InnerException.Message;
                    string argmesmsg1 = "Invoke_Module Fail!";
                    strException = CombineXMLException(defWSErrCode, argsysmsg1, argmesmsg1, ex.StackTrace);
                }
                string argReturnValue = "";
                string argResult = "fail";
                string argMessage = "";
                result = CombineXMLResponse(strIdentity, argReturnValue, strException, argResult, argMessage);
            }

            // 記錄執行結束時間.
            stpCostTime.Stop();
            datEndTime = DateTime.Now;

            // 執行時間紀錄 
            if (blnLogOn)
            {

                long Duration = 0L;
                string InXml;
                string UserNo = "N/A";
                string ComputerName = "N/A";

                var XmlDoc = new System.Xml.XmlDocument();

                try
                {

                    // 取出開始到結束的執行時間(毫秒為單位).
                    Duration = stpCostTime.ElapsedMilliseconds;

                    // 取出 InXml
                    // 2019/08/27 OwenLiu, Mantis:0061520, 修正invokeSrv啟用CI/CO 效能監控 與之前版本不相容問題
                    if (parameters != null && parameters.Length > 0)
                    {
                        string strBooleanValueTmp = "";
                        if (intParameterLength < parameters.Length && IsBoolean(parameters[parameters.Length - 1].ToString(), ref strBooleanValueTmp))
                        {
                            InXml = parameters[parameters.Length - 2].ToString();
                            // 讀取 InXml字串
                            XmlDoc.LoadXml(InXml);
                            // 取出 UserNo,ComputerName
                            UserNo = GetXMLCurUserNo(XmlDoc);
                            ComputerName = GetXMLCurComputer(XmlDoc);
                        }
                        else
                        {
                            InXml = parameters[parameters.Length - 1].ToString();
                            // 讀取 InXml字串
                            XmlDoc.LoadXml(InXml);
                            // 取出 UserNo,ComputerName
                            UserNo = GetXMLCurUserNo(XmlDoc);
                            ComputerName = GetXMLCurComputer(XmlDoc);
                        }
                    }
                }

                catch (Exception ex)
                {
                }

                finally
                {
                    XmlDoc = null;
                }

                // 記錄Log
                using (var objSYS = new kcSYS.clsSYSUserLog())
                {
                    try
                    {
                        objSYS.AddMESTransactionLog(UserNo, strComponent, strClassName, strMethodName, datStartTime, datEndTime, Duration, ComputerName);
                    }

                    catch (Exception ex)
                    {
                        objSYS.AddErrorLog("wsInvoke.Invoke_Module", UserNo, "AddMESTransactionLog", method, datEndTime, ex.Message, ComputerName: ComputerName);
                    }
                }

            }

            return result;

        }

        private string InvokeFunction_Module(iMESCore.Base._enuInvokeType pInvokeType, string InXml, ref object pClass, string pMethod, string pServiceName, string[] pLogKeyFields = null, DataSet pDataSetParameter = null)
        {
            string InvokeFunction_ModuleRet = default(string);

            object[] ArgsValue;

            System.Reflection.ParameterInfo[] aryParameterInfo = pClass.GetType().GetMethod(pMethod).GetParameters();
            var dicParameter = new Dictionary<string, object>();
            string strIdentity = default(string), strNode, strException = default(string), strResult = default(string), strTemp;
            string strReturnValue = "";
            string strKeyFields = "";
            string strKeyValues = "";

            var XmlDoc = new XmlDocument();
            var ArriveTime = DateTime.Now;
            bool blnAddEventLog = false;
            try
            {

                // 讀取InXml字串
                XmlDoc.LoadXml(InXml);
                // 組Identity字串
                string argComputerName = Environment.MachineName;
                string argCurUserNo = GetXMLCurUserNo(XmlDoc);
                string argSendTime = Convert.ToString(ArriveTime);
                strIdentity = CombineXMLIdentity(argComputerName, argCurUserNo, argSendTime);
                ArriveTime = Convert.ToDateTime(argSendTime);

                ArgsValue = new object[aryParameterInfo.Length];

                // 確認參數及參數預設值，並拆解xml取需要的參數值
                for (int inti = 0, loopTo = aryParameterInfo.Length - 1; inti <= loopTo; inti++)
                {

                    // 給定參數預設值
                    try
                    {
                        ArgsValue[inti] = aryParameterInfo[inti].DefaultValue;
                    }
                    catch (Exception)
                    {
                        ArgsValue[inti] = default(DateTime);
                    }

                    // 以參數名稱當做節點
                    strNode = aryParameterInfo[inti].Name.ToLower();

                    if (aryParameterInfo[inti].Name == "AdditionalXml")
                    {

                        if (XmlDoc.DocumentElement.GetElementsByTagName("additional").Count > 0)
                        {
                            ArgsValue[inti] = XmlDoc.DocumentElement.GetElementsByTagName("additional").Item(0).OuterXml;
                        }
                    }

                    // 依value數量判定傳入的為
                    else if (XmlDoc.DocumentElement.GetElementsByTagName(strNode).Count > 0 && XmlDoc.GetElementsByTagName(strNode).Item(0).SelectNodes("value").Count > 0)
                    {

                        // 一般變數
                        strTemp = XmlDoc.DocumentElement.GetElementsByTagName(strNode).Item(0).SelectNodes("value").Item(0).InnerText;
                        // 檢查資料型態是否符合
                        switch (aryParameterInfo[inti].ParameterType.Name)
                        {
                            case "String":
                                {
                                    // 字串型態無需特別檢查
                                    ArgsValue[inti] = strTemp;
                                    break;
                                }
                            case "Int16":
                                {
                                    if (!Information.IsNumeric(strTemp))
                                        throw new iMESException.MESException("0000-200011", "[%" + strNode + "%]");
                                    ArgsValue[inti] = Conversions.ToShort(strTemp);
                                    break;
                                }
                            case "Integer":
                            case "Int32":
                                {
                                    if (!Information.IsNumeric(strTemp))
                                        throw new iMESException.MESException("0000-200011", "[%" + strNode + "%]");
                                    ArgsValue[inti] = Conversions.ToInteger(strTemp);
                                    break;
                                }
                            case "Long":
                            case "Int64":
                                {
                                    if (!Information.IsNumeric(strTemp))
                                        throw new iMESException.MESException("0000-200011", "[%" + strNode + "%]");
                                    ArgsValue[inti] = Conversions.ToLong(strTemp);
                                    break;
                                }
                            case "Double":
                                {
                                    if (!Information.IsNumeric(strTemp))
                                        throw new iMESException.MESException("0000-200011", "[%" + strNode + "%]");
                                    ArgsValue[inti] = Convert.ToDouble(strTemp);
                                    break;
                                }
                            case "Decimal":
                                {
                                    if (!Information.IsNumeric(strTemp))
                                        throw new iMESException.MESException("0000-200011", "[%" + strNode + "%]");
                                    ArgsValue[inti] = Convert.ToDecimal(strTemp);
                                    break;
                                }
                            case "DateTime":
                                {
                                    if (!Information.IsDate(strTemp))
                                        throw new iMESException.MESException("0000-200012", "[%" + strNode + "%]");
                                    ArgsValue[inti] = Convert.ToDateTime(strTemp);
                                    break;
                                }
                            case "Boolean":
                                {
                                    string argstrBooleanValue = "Null";
                                    if (!IsBoolean(strTemp, strBooleanValue: ref argstrBooleanValue))
                                        throw new iMESException.MESException("0000-200012", "[%" + strNode + "%]");
                                    ArgsValue[inti] = Convert.ToBoolean(strTemp);
                                    break;
                                }
                            case "DataTable":
                                {
                                    ArgsValue[inti] = funXmlToDataTable(XmlDoc.GetElementsByTagName(strNode).Item(0).OuterXml, strNode);
                                    break;
                                }

                            default:
                                {
                                    throw new iMESException.MESException("0000-003000", "Unhandled data type in 「InvokeFunction」, Please Contact RD Members. ");
                                }
                        }

                        dicParameter.Add(aryParameterInfo[inti].Name, ArgsValue[inti]);
                    }
                    else if (aryParameterInfo[inti].ParameterType.Name.StartsWith("DataTable"))
                    {
                        // 若無資料，重新定義DataTable = nothing
                        ArgsValue[inti] = null;
                    }
                    else if (aryParameterInfo[inti].ParameterType.Name.StartsWith("DataSet"))
                    {
                        // 若參數為DataSet
                        ArgsValue[inti] = pDataSetParameter;
                    }
                    else if ((int)System.Reflection.ParameterAttributes.HasDefault == Conversions.ToInteger(false))
                    {
                        // 參數沒有預設值(為必要欄位)，又找不到資料則Throw Exception
                        throw new iMESException.MESException("0000-200002", strNode + " Not Found!");
                    }
                }

                if (!(pLogKeyFields == null))
                {
                    strKeyFields = Strings.Join(pLogKeyFields, ",");
                    foreach (string strField in pLogKeyFields)
                        strKeyValues = strKeyValues + dicParameter[strField].ToString() + ",";
                    if (strKeyValues.EndsWith(","))
                    {
                        strKeyValues = Strings.Mid(strKeyValues, 1, strKeyValues.Length - 1);
                    }
                }

                switch (pInvokeType)
                {
                    case iMESCore.Base._enuInvokeType._Load:
                        strReturnValue = Convert.ToString(pClass.GetType().GetMethod(pMethod).Invoke(pClass, ArgsValue));
                        break;
                    case iMESCore.Base._enuInvokeType._Add:
                    case iMESCore.Base._enuInvokeType._Edit:
                    case iMESCore.Base._enuInvokeType._Delete:
                        pClass.GetType().GetMethod(pMethod).Invoke(pClass, ArgsValue);

                        // 記錄EventLog
                        using (var objSYS = new kcSYS.clsSYSUserLog())
                        {
                            objSYS.AddEventLog(pServiceName, GetXMLCurUserNo(XmlDoc), strKeyFields, strKeyValues, DateTime.Now, pMethod);
                        }

                        break;
                }

                strException = "";
                strResult = "success";
            }

            catch (iMESException.MESException ex)
            {

                strReturnValue = "";
                if (ex.InnerException == null)
                {
                    string argcode = Convert.ToString(ex.ErrorCode);
                    string argsysmsg = TranslateMsg(ex.Message, GetXMLLanguageMode(XmlDoc), strResourceDir);
                    string argmesmsg = pMethod +
                        (string.IsNullOrEmpty(strKeyValues) ? "" : " : (" + strKeyValues + ") ") + " Failed!";
                    strException = CombineXMLException(argcode, argsysmsg, argmesmsg, ex.StackTrace);
                }
                else
                {
                    string argcode1 = Convert.ToString(ex.ErrorCode);
                    string argsysmsg1 = TranslateMsg(ex.InnerException.Message, GetXMLLanguageMode(XmlDoc), strResourceDir);
                    string argmesmsg1 = pMethod +
                        (string.IsNullOrEmpty(strKeyValues) ? "" : " : (" + strKeyValues + ") ") + " Failed!";
                    strException = CombineXMLException(argcode1, argsysmsg1, argmesmsg1, ex.StackTrace);
                }

                strResult = "fail";

                using (var objSYS = new kcSYS.clsSYSUserLog())
                {
                    objSYS.AddErrorLog(pServiceName, GetXMLCurUserNo(XmlDoc), strKeyFields, strKeyValues, DateTime.Now, strException, ComputerName: GetXMLCurComputer(XmlDoc));
                }
            }

            catch (Exception ex)
            {

                strReturnValue = "";
                if (ex.InnerException == null)
                {
                    string argsysmsg = ex.Message;
                    string argmesmsg = pMethod +
                        (string.IsNullOrEmpty(strKeyValues) ? "" : " : (" + strKeyValues + ") ") + " Failed!";
                    strException = CombineXMLException(defWSErrCode, argsysmsg, argmesmsg, ex.StackTrace);
                }
                else
                {
                    string argsysmsg1 = ex.InnerException.Message;
                    string argmesmsg1 = pMethod +
                        (string.IsNullOrEmpty(strKeyValues) ? "" : " : (" + strKeyValues + ") ") + " Failed!";
                    strException = CombineXMLException(defWSErrCode, argsysmsg1, argmesmsg1, ex.StackTrace);
                }
                strResult = "fail";

                using (var objSYS = new kcSYS.clsSYSUserLog())
                {
                    objSYS.AddErrorLog(pServiceName, GetXMLCurUserNo(XmlDoc), strKeyFields, strKeyValues, DateTime.Now, strException, ComputerName: GetXMLCurComputer(XmlDoc));
                }
            }
            finally
            {

                // 將各部份之XML字串組起來並傳出
                string argMessage = "";
                InvokeFunction_ModuleRet = CombineXMLResponse(strIdentity, strReturnValue, strException, strResult, argMessage);

                dicParameter = null;
                XmlDoc = null;
            }

            return InvokeFunction_ModuleRet;

        }

        private static DataTable funXmlToDataTable(string InXML, string TagName)
        {
            var tmpStringReader = default(StringReader); // 將字串轉換成可讀入DataSet的物件
            var xmlDoc = new XmlDocument();
            string XmlData; // 儲存取回之資料
            var dsTemp = new DataSet();
            string strXml = "";

            try
            {
                xmlDoc.LoadXml(InXML);
                // 只取出Value()
                for (int i = 0, loopTo = xmlDoc.GetElementsByTagName(TagName).Item(0).SelectNodes("value").Count - 1; i <= loopTo; i++)
                    strXml += xmlDoc.GetElementsByTagName(TagName).Item(0).SelectNodes("value").Item(i).OuterXml;
                strXml = CombineXMLValue(TagName, strXml);
                tmpStringReader = new StringReader(strXml);
                dsTemp.ReadXml(tmpStringReader);
                tmpStringReader.Close();
                // 重新命名Table Name
                dsTemp.Tables[0].TableName = TagName;
                return dsTemp.Tables[0];
            }

            catch (Exception ex)
            {
                throw;
            }
            finally
            {
                if (!(tmpStringReader == null))
                    tmpStringReader.Close();
                if (!(dsTemp == null))
                    dsTemp.Dispose();
            }


        }


        #region 行動報工
        /// <summary>
        /// 2019/02/13 OwenLiu, 標準版WS增加 InvokeSrv_json共用函式，供前端介面直接叫用
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke Web Service Resolved json")]
        public string invokeSrv_json(string uri, string content)
        {

            object result;
            string strResponse = "";
            string strMessage = "";
            string method = "";
            string strClassName = "";
            string strMethodName = "";
            string strComponent = "";
            string execptionStack = "";
            string[] aryTemp;
            string typeName;
            Type t;
            MethodInfo mi;
            Type[] argumentTypes;
            ConstructorInfo ctor;
            object obj;
            string strSendTime = "";
            var ometadata = new Dictionary<string, string>();
            var oResponseMsg = new iMESCIO.CDO.Common.RsponseMessage();
            string strCompumterName = Environment.MachineName;
            string strUserNo = "PAD";
            string strSessionNo = "";
            string strExceptionMethodName = "";

            do
            {
                try
                {
                    if (uri == null || string.IsNullOrEmpty(uri.Trim()) || string.IsNullOrEmpty(uri))
                    {
                        break;
                    }
                    // If (parameter Is Nothing) OrElse (parameter.Trim = "") OrElse (String.IsNullOrEmpty(parameter)) Then
                    // Exit Try
                    // End If

                    object argobjSource = DateTime.Now;
                    strSendTime = funTransVarFormat(argobjSource, "yyyy/MM/dd HH:mm:ss");

                    // 2020/04/24 雋辰,修改為非json也給予基礎參數
                    try
                    {
                        ometadata = DeserializeObject<Dictionary<string, string>>(uri);
                        if (ometadata.ContainsKey("computername"))
                            strCompumterName = ometadata["computername"];
                        if (ometadata.ContainsKey("userid"))
                            strUserNo = ometadata["userid"];
                        if (ometadata.ContainsKey("sessionno"))
                            strSessionNo = ometadata["sessionno"];
                    }
                    catch (Exception ex)
                    {
                        ometadata.Add("method", uri);
                        ometadata.Add("languagemode", "en");
                    }

                    // 2020/04/27 雋辰,Check Session
                    CheckSession(strSessionNo);

                    if (!ometadata.ContainsKey("method"))
                        break;
                    method = ometadata["method"];
                    aryTemp = method.Split('.');

                    if (aryTemp.Length < 2 || aryTemp.Length > 3)
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    if (aryTemp.Length == 2)
                    {
                        strComponent = "wsSTD.dll";
                        strClassName = aryTemp[0];
                        strMethodName = aryTemp[1];
                    }
                    else if (aryTemp.Length == 3 && aryTemp[1].StartsWith("ws") == false)  // 2017-06-09, Joe, 不透過ws直接Call kc/tc/ud
                    {
                        // 前端傳入：kcXXX.clsXXX.AddXXXXX
                        strComponent = aryTemp[0] + ".dll";   // dll name
                        strClassName = aryTemp[1];   // class name
                        strMethodName = aryTemp[2];  // function name
                    }
                    else
                    {
                        strComponent = "ws" + aryTemp[0] + ".dll";
                        strClassName = aryTemp[1];
                        strMethodName = aryTemp[2];
                    }

                    if (string.IsNullOrEmpty(strComponent) || string.IsNullOrEmpty(strClassName) || string.IsNullOrEmpty(strMethodName))
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    try
                    {
                        // result = mi.Invoke(obj, New Object() {metadata, parameter})

                        result = InvokeFunction_json(ref execptionStack, method, DeserializeObject<Dictionary<string, object>>(content), ometadata["languagemode"], strUserNo, strCompumterName);

                        oResponseMsg.Code = 0.ToString();
                        oResponseMsg.ResultJson = Convert.ToString(result);

                        strResponse = DataExchange.CombineRsponseMessage(oResponseMsg, language: ometadata["languagemode"].ToString());

                        // 2020/07/28 雋辰,行動報工接口加入log
                        try
                        {
                            var strBulder = new System.Text.StringBuilder();
                            strBulder.AppendLine("Method:" + method);
                            strBulder.AppendLine("Content:" + content);
                            strBulder.Append("Response:" + strResponse);
                            Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Info, null);
                        }
                        catch (Exception ex)
                        {
                            Log.WriteLog("WriteLog Info fail:" + method, iMESLog.iMESLogLevel.Warn, ex);
                        }
                    }

                    catch (Exception ex)
                    {
                        var strBulder = new System.Text.StringBuilder();
                        strBulder.AppendLine("Method:" + method);
                        strBulder.Append("Content:" + content);
                        if (!string.IsNullOrEmpty(execptionStack))
                        {
                            strBulder.AppendLine("");
                            strBulder.Append("Stack:" + execptionStack);
                        }
                        if (!(ex.InnerException == null) && ex is TargetInvocationException)
                        {
                            strResponse = DataExchange.CombineRsponseMessage(ex: ex.InnerException, language: ometadata["languagemode"].ToString(), stack: execptionStack, resourceDir: strResourceDir);
                            Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Error, ex.InnerException);
                        }
                        else
                        {
                            strResponse = DataExchange.CombineRsponseMessage(ex: ex, language: ometadata["languagemode"].ToString(), stack: execptionStack, resourceDir: strResourceDir);
                            Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Error, ex);
                        }
                    }
                }
                catch (Exception ex)
                {
                    strExceptionMethodName = ometadata["method"];
                    strResponse = DataExchange.CombineRsponseMessage(ex: ex, language: ometadata["languagemode"], stack: execptionStack, resourceDir: strResourceDir);
                }
            }
            while (false);

            return strResponse;

        }

        /// <summary>
        /// 2020/04/24 雋辰,執行底層功能
        /// </summary>
        /// <param name="uri">json string , Example: {method:kcXXX.cs.function,kcXXX.cs.function} </param>
        /// <param name="content">json string , Invoke Function args</param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke any library , Available for PAD , Method allows multiple ',' to separate")]
        public string InvokeSrv_Json_Multi(string uri, string content)
        {

            string strResponse = "";
            var response = new iMESCIO.CDO.Common.RsponseMessage();
            var resultJson = new Newtonsoft.Json.Linq.JObject();

            string strCompumterName = Environment.MachineName;
            string strUserNo = "PAD";
            string strSessionNo = "";
            string strExceptionMethod = "";
            string execptionStack = "";
            var method = default(string);
            string tempMethod;
            Newtonsoft.Json.Linq.JToken tempToken;
            List<string> methods;
            List<object> pars;
            Dictionary<string, object> par;
            var ometadata = new Dictionary<string, object>();

            do
            {
                try
                {
                    if (uri == null || string.IsNullOrEmpty(uri.Trim()) || string.IsNullOrEmpty(uri))
                    {
                        break;
                    }
                    if (content == null || string.IsNullOrEmpty(content.Trim()) || string.IsNullOrEmpty(content))
                    {
                        break;
                    }

                    // 前端傳入：function name
                    try
                    {
                        ometadata = DeserializeObject<Dictionary<string, object>>(uri);
                        if (ometadata.ContainsKey("computername"))
                            strCompumterName = ometadata["computername"].ToString();
                        if (ometadata.ContainsKey("userid"))
                            strUserNo = ometadata["userid"].ToString();
                        if (ometadata.ContainsKey("sessionno"))
                            strSessionNo = ometadata["sessionno"].ToString();
                    }
                    catch (Exception ex)
                    {
                        ometadata.Add("method", SerializeObject(uri.Split(',')));
                        ometadata.Add("languagemode", "en");
                    }

                    try
                    {
                        methods = DeserializeObject<List<string>>(ometadata["method"].ToString());
                        pars = DeserializeObject<List<object>>(content);
                    }
                    catch (Exception ex)
                    {
                        throw new iMESException.MESException("0000-200091", "Json [%Format Error%]");
                    }

                    // 2020/04/27 雋辰,Check Session
                    CheckSession(strSessionNo);

                    var transferGlobal = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                    var transferSingle = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                    for (int i = 0, loopTo = methods.Count - 1; i <= loopTo; i++)
                    {
                        method = methods[i];

                        // 取得key Name,避免請求重複函式導致Catch
                        tempMethod = method;
                        tempToken = resultJson[tempMethod];
                        if (!(tempToken == null))
                        {
                            int index = 2;
                            do
                            {
                                tempMethod = string.Format("{0}({1})", method, index);
                                tempToken = resultJson[tempMethod];
                                index += 1;
                            }
                            while (tempToken != null);
                        }

                        // 取得Function 參數
                        par = pars.Count > i ? DeserializeObject<Dictionary<string, object>>(pars[i].ToString()) : null;

                        resultJson.Add(tempMethod, InvokeFunction_json(ref execptionStack, method, par, ometadata["languagemode"].ToString(), strUserNo, strCompumterName, transferGlobal, transferSingle));
                    }

                    response.Code = defSuccessCode;
                    response.ResultJson = SerializeObject(resultJson);

                    strResponse = DataExchange.CombineRsponseMessage(response, language: ometadata["languagemode"].ToString());

                    // 2020/07/28 雋辰,行動報工接口加入log
                    string strMethods = "";
                    try
                    {
                        foreach (string m in methods)
                            strMethods += m + ",";
                        strMethods = strMethods.TrimEnd(',');
                    }
                    catch (Exception ex)
                    {
                    }
                    try
                    {
                        var strBulder = new System.Text.StringBuilder();
                        strBulder.AppendLine("Method:" + strMethods);
                        strBulder.AppendLine("Content:" + content);
                        strBulder.Append("Response:" + strResponse.Replace(@"\\", ""));
                        Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Info);
                    }
                    catch (Exception ex)
                    {
                        Log.WriteLog("WriteLog Info fail:" + strMethods, iMESLog.iMESLogLevel.Warn, ex);
                    }
                }

                catch (Exception ex)
                {
                    strExceptionMethod = method;
                    var strBulder = new System.Text.StringBuilder();
                    strBulder.AppendLine("Method:" + method);
                    strBulder.Append("Content:" + content);
                    if (!string.IsNullOrEmpty(execptionStack))
                    {
                        strBulder.AppendLine("");
                        strBulder.Append("Stack:" + execptionStack);
                    }
                    if (!(ex.InnerException == null) && ex is TargetInvocationException)
                    {
                        strResponse = DataExchange.CombineRsponseMessage(ex: ex.InnerException, language: ometadata["languagemode"].ToString(), stack: execptionStack, resourceDir: strResourceDir);
                        Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Error, ex.InnerException);
                    }
                    else
                    {
                        strResponse = DataExchange.CombineRsponseMessage(ex: ex, language: ometadata["languagemode"].ToString(), stack: execptionStack, resourceDir: strResourceDir);
                        Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Error, ex);
                    }
                }
            }
            while (false);

            return strResponse;

        }

        /// <summary>
        /// 2020/06/09 雋辰,新增summary,執行底層函式
        /// </summary>
        /// <param name="method">函式名稱</param>
        /// <param name="args">函式引數</param>
        /// <param name="language">語系</param>
        /// <param name="userNo">使用者編號</param>
        /// <param name="computerName">電腦名稱資訊</param>
        /// <param name="transferGlobal">函式引數表全域</param>
        /// <param name="transferSingle">函式引數表,只使用一次</param>
        /// <returns></returns>
        private string InvokeFunction_json(ref string stack, string method, Dictionary<string, object> args = null, string language = "", string userNo = "", string computerName = "", Dictionary<string, object> transferGlobal = null, Dictionary<string, object> transferSingle = null)
        {
            string result;

            string[] aryTemp;
            string dllName;
            string csName;
            var methodName = default(string);
            var logFlag = default(bool);
            string[] columns = null;
            var listTransfer = default(List<Newtonsoft.Json.Linq.JToken>);
            iMESCore.Base._enuInvokeType methodType;
            var refParameters = new Dictionary<short, string>();
            string[] aryMTypes;        // 20211202 13871,多載Method使用
            var m_types = default(List<Type>);      // 20211202 13871,多載Method使用

            Assembly assembly;
            Type t;
            MethodInfo mi;
            Type miReturnType;
            var miParameters = default(ParameterInfo[]);
            var argsIgnoreCase = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
            object[] parameters;
            var copyParameters = default(object[]);
            object miResult;
            bool changeToXml = false;
            bool notXml = false;

            var objSYS = new kcSYS.clsSYSUserLog();

            // 79915:  效能監控擴充 2020/10/20 效能監控 Edison
            // ==============================================79915 Start ==============================================
            DateTime datStartTime, datEndTime;
            var stpCostTime = new Stopwatch();

            try
            {

                // 記錄執行開始時間.
                stpCostTime.Start();
                datStartTime = DateTime.Now;
                // ==============================================79915  End  ==============================================

                // 解析請求
                aryTemp = method.Split('.');
                if (aryTemp.Length == 2)
                {
                    dllName = "wsSTD.dll";
                    csName = aryTemp[0];
                    methodName = aryTemp[1].Replace(".", "_");
                }
                else if (aryTemp.Length == 3)
                {
                    // 前端傳入：kcXXX.clsXXX.AddXXXXX
                    dllName = aryTemp[0] + ".dll";   // dll name
                    csName = aryTemp[1];   // class name
                    methodName = aryTemp[2].Replace(".", "_");  // function name
                }
                else
                {
                    throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                }

                // 將參數值移至忽略大小寫的Dictionary
                if (!(args == null))
                {
                    foreach (string key in args.Keys)
                        argsIgnoreCase[key] = args[key];
                }

                // 取出指定欄位參數
                if (argsIgnoreCase.ContainsKey("Columns"))
                {
                    columns = DeserializeObject<string[]>(argsIgnoreCase["Columns"].ToString());
                    argsIgnoreCase.Remove("Columns");
                }

                // 20211202 13871,多載Method使用
                var dicTypes = new Dictionary<string, Type>();     // 儲存名稱對應的Type避免每次都要從GetAssemblies尋找
                if (argsIgnoreCase.ContainsKey("m_Types"))
                {
                    aryMTypes = DeserializeObject<string[]>(argsIgnoreCase["m_Types"].ToString());
                    m_types = new List<Type>();
                    for (int i = 0, loopTo = aryMTypes.Length - 1; i <= loopTo; i++)
                    {
                        string strName = aryMTypes[i];
                        Type t_pars;

                        t_pars = Type.GetType(strName);

                        if (t_pars == null)
                        {
                            if (dicTypes.ContainsKey(strName))
                            {
                                t_pars = dicTypes[strName];
                            }
                            else
                            {
                                foreach (Assembly item in AppDomain.CurrentDomain.GetAssemblies())
                                {
                                    var t_temp = item.GetType(strName);
                                    if (t_temp != null)
                                    {
                                        t_pars = t_temp;
                                        break;
                                    }
                                }
                                if (t_pars == null)
                                    throw new iMESException.MESException("0000-200091", string.Format("{0} [%IS NOT EXIST%]", strName));

                                dicTypes[strName] = t_pars;
                            }
                        }

                        m_types.Add(t_pars);
                    }
                }

                // 取出傳遞引數參數
                if (argsIgnoreCase.ContainsKey("m_Transfer"))
                {
                    listTransfer = DeserializeObject<List<Newtonsoft.Json.Linq.JToken>>(argsIgnoreCase["m_Transfer"].ToString());
                    argsIgnoreCase.Remove("m_Transfer");
                }

                //20240522,13871,即便呼叫不是ws但是有傳入此參數,遇到INXML參數也會將json轉為xml
                if (argsIgnoreCase.ContainsKey("m_ChangeToXml"))
                {
                    if (argsIgnoreCase["m_ChangeToXml"] != null)
                        bool.TryParse(argsIgnoreCase["m_ChangeToXml"].ToString(), out changeToXml);
                    argsIgnoreCase.Remove("m_ChangeToXml");
                }

                //20240531,13871,即便呼叫ws也不處理InXml
                if (argsIgnoreCase.ContainsKey("m_NotXml"))
                {
                    if (argsIgnoreCase["m_NotXml"] != null)
                        bool.TryParse(argsIgnoreCase["m_NotXml"].ToString(), out notXml);
                    argsIgnoreCase.Remove("m_NotXml");
                }

                // 判斷method類型,後續結果處理的依據
                string tmpMethodName = methodName.ToUpper();
                if (tmpMethodName.StartsWith("LOAD"))
                    methodType = iMESCore.Base._enuInvokeType._Load;
                else if (tmpMethodName.StartsWith("SHOW"))
                    methodType = iMESCore.Base._enuInvokeType._Show;
                else if (tmpMethodName.StartsWith("GET"))
                    methodType = iMESCore.Base._enuInvokeType._Get;
                else if (tmpMethodName.StartsWith("ADD"))
                    methodType = iMESCore.Base._enuInvokeType._Add;
                else if (tmpMethodName.StartsWith("EDIT"))
                    methodType = iMESCore.Base._enuInvokeType._Edit;
                else if (tmpMethodName.StartsWith("DEL"))
                    methodType = iMESCore.Base._enuInvokeType._Delete;
                else
                    methodType = iMESCore.Base._enuInvokeType._Unknow;

                // 判斷需不需要紀錄Ws Log,wsSTD的函式內已經有Log
                logFlag = !dllName.StartsWith("ws") && ((int)methodType >= 1 && (int)methodType <= 3 || (int)methodType < 0) ? true : false;

                assembly = Assembly.Load(AssemblyName.GetAssemblyName(Path.Combine(HttpContext.Current.Server.MapPath("bin"), dllName)));
                t = assembly.GetType(string.Format("{0}.{1}", assembly.GetName().Name, csName), true, true);
                // 20211202 13871,多載Method使用
                if (m_types == null)
                {
                    mi = t.GetMethod(methodName);
                }
                else
                {
                    mi = t.GetMethod(methodName, m_types.ToArray());
                }
                if (mi == null)
                    throw new iMESException.MESException("0000-200091", string.Format("{0} [%IS NOT EXIST%]", method));
                miReturnType = mi.ReturnType;

                miParameters = mi.GetParameters();

                // 建立函式所需參數
                if (miParameters.Length <= 0)
                {
                    // 20220314 13871,增加錯誤卡控
                    parameters = null;
                    copyParameters = null;
                }
                else
                {
                    parameters = new object[miParameters.Length];
                    copyParameters = new object[miParameters.Length];
                    for (int i = 0, loopTo1 = miParameters.Length - 1; i <= loopTo1; i++)
                    {
                        string parName = miParameters[i].Name;
                        var parType = miParameters[i].ParameterType;

                        if (miParameters[i].IsOut || miParameters[i].ParameterType.IsByRef)
                        {
                            refParameters.Add((short)i, parName);
                            parType = parType.GetElementType();
                        }

                        if (parName.ToUpper() == "INXML" && ((dllName.StartsWith("ws") && notXml == false) || changeToXml))
                        {
                            // 2020/07/28 雋辰,parameter to xml
                            string argSendTime = Convert.ToString(DateTime.Now);
                            string strIdentity = CombineXMLIdentity(computerName, userNo, argSendTime, language);
                            string strParameter = DataExchange.Parameter2XML(argsIgnoreCase, transferGlobal, transferSingle);
                            string inXML = CombineXMLRequest(strIdentity, strParameter);
                            parameters[i] = inXML;
                        }
                        else if (argsIgnoreCase.ContainsKey(parName))
                        {
                            try
                            {
                                // 20210118 雋辰,避免空字串被JsonConvert轉為Nothing
                                if (!(argsIgnoreCase[parName] == null) && string.IsNullOrEmpty(argsIgnoreCase[parName].ToString()))
                                {
                                    parameters[i] = Convert.ChangeType(argsIgnoreCase[parName].ToString(), parType);
                                }
                                else
                                {
                                    // 20210513 13871,MantisBT:0092632,DataTable轉型傳入自定義JsonConvert方式,排除浮點數被轉成整數問題
                                    JsonSerializerSettings settings = new JsonSerializerSettings() { Converters = new[] { new TypeInferringDataTableConverter() } };
                                    if (ReferenceEquals(parType, typeof(DataTable)))
                                    {
                                        parameters[i] = JsonConvert.DeserializeObject(argsIgnoreCase[parName].ToString(), parType, settings);
                                    }
                                    else
                                    {
                                        parameters[i] = DeserializeObject(argsIgnoreCase[parName].ToString(), parType);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                try
                                {
                                    parameters[i] = Convert.ChangeType(argsIgnoreCase[parName], parType);
                                }
                                catch (Exception ex2)
                                {
                                    parameters[i] = argsIgnoreCase[parName];
                                }
                            }
                        }
                        else if (!(transferSingle == null) && transferSingle.ContainsKey(parName))
                        {
                            try
                            {
                                parameters[i] = Convert.ChangeType(transferSingle[parName], parType);
                            }
                            catch (Exception ex)
                            {
                                parameters[i] = transferSingle[parName];
                            }
                        }
                        else if (!(transferGlobal == null) && transferGlobal.ContainsKey(parName))
                        {
                            try
                            {
                                parameters[i] = Convert.ChangeType(transferGlobal[parName], parType);
                            }
                            catch (Exception ex)
                            {
                                parameters[i] = transferGlobal[parName];
                            }
                        }
                        else
                        {
                            if (miParameters[i].IsOptional == false)
                                throw new iMESException.MESException("0000-200002", string.Format("[%{0}%] [%IS EMPTY%]", parName));
                            try
                            {
                                parameters[i] = miParameters[i].DefaultValue;
                            }
                            catch (Exception)
                            {
                                if (parType == typeof(DateTime))
                                    parameters[i] = default(DateTime);
                                else
                                    throw;
                            }
                        }
                    }
                }
                // 20210118 雋辰,複製傳入的參數陣列,避免ref值被改變,記錄log用
                // 20220314 13871,增加錯誤卡控
                if (parameters != null && copyParameters != null)
                    parameters.CopyTo(copyParameters, 0);

                // 執行函式
                miResult = mi.Invoke(Activator.CreateInstance(t), parameters);

                // 清除已使用的transferSingle
                if (!(transferSingle == null))
                    transferSingle.Clear();

                // 結果 處理
                if (miReturnType.Equals(typeof(DataSet)))
                {
                    DataSet ds = miResult as DataSet;
                    DataExchange.ColumnName_ToUpper(ds);

                    result = SerializeObject(DataExchange.Specify_Field(ds, new List<string[]>() { columns }));
                    var jObj = DeserializeObject(result);
                    Newtonsoft.Json.Linq.JObject argjObj = (Newtonsoft.Json.Linq.JObject)jObj;
                    DataExchange.PorcessRef(ref argjObj, parameters, refParameters);
                    jObj = argjObj;
                    result = SerializeObject(jObj);

                    // 處理傳遞引數
                    DataExchange.ProcessTransfer_Load(listTransfer, (Newtonsoft.Json.Linq.JObject)jObj, ref transferGlobal, ref transferSingle);
                }
                else if (miReturnType.Equals(typeof(DataTable)))
                {
                    DataTable dt = miResult as DataTable;
                    var ds = new DataSet();
                    ds.Tables.Add(dt);
                    DataExchange.ColumnName_ToUpper(ds);
                    result = SerializeObject(DataExchange.Specify_Field(ds, new List<string[]>() { columns }));
                    var jObj = DeserializeObject(result);
                    Newtonsoft.Json.Linq.JObject argjObj1 = (Newtonsoft.Json.Linq.JObject)jObj;
                    DataExchange.PorcessRef(ref argjObj1, parameters, refParameters);
                    jObj = argjObj1;
                    result = SerializeObject(jObj);

                    // 處理傳遞引數
                    DataExchange.ProcessTransfer_Load(listTransfer, (Newtonsoft.Json.Linq.JObject)jObj, ref transferGlobal, ref transferSingle);
                }
                else if (miReturnType.Equals(typeof(DataRow)))
                {
                    DataRow row = miResult as DataRow;
                    var dt = row.Table.Clone();
                    var ds = new DataSet();
                    var dr = dt.NewRow();
                    for (int i = 0, loopTo2 = dr.Table.Columns.Count - 1; i <= loopTo2; i++)
                        dr[i] = row[i];
                    dt.Rows.Add(dr);
                    ds.Tables.Add(dt);
                    DataExchange.ColumnName_ToUpper(ds);

                    result = SerializeObject(DataExchange.Specify_Field(ds, new List<string[]>() { columns }));
                    var jObj = DeserializeObject(result);
                    Newtonsoft.Json.Linq.JObject argjObj2 = (Newtonsoft.Json.Linq.JObject)jObj;
                    DataExchange.PorcessRef(ref argjObj2, parameters, refParameters);
                    jObj = argjObj2;
                    result = SerializeObject(jObj);

                    // 處理傳遞引數
                    DataExchange.ProcessTransfer_Load(listTransfer, (Newtonsoft.Json.Linq.JObject)jObj, ref transferGlobal, ref transferSingle);
                }
                else if ((dllName.StartsWith("ws") && notXml == false) || changeToXml)
                {
                    // 2020/07/28 雋辰,處理wsSTD類的Result
                    try
                    {
                        var jObj = DataExchange.XmlString2JsonObj_wsSTD(ref stack, miResult.ToString(), columns, language, strResourceDir);
                        DataExchange.PorcessRef(ref jObj, parameters, refParameters);
                        result = SerializeObject(jObj);

                        // 處理傳遞引數
                        DataExchange.ProcessTransfer(listTransfer, jObj, ref transferGlobal, ref transferSingle);
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }
                }
                else
                {
                    switch (methodType)
                    {
                        case iMESCore.Base._enuInvokeType._Load:
                        case iMESCore.Base._enuInvokeType._Show:
                            // Load函式Return XML,將XML string轉成DataSet
                            Newtonsoft.Json.Linq.JObject jObj;
                            if (miResult == null)
                            {
                                jObj = DataExchange.XmlString2JsonObj("", columns);
                            }
                            else
                            {
                                jObj = DataExchange.XmlString2JsonObj(miResult.ToString(), columns);
                            }

                            DataExchange.PorcessRef(ref jObj, parameters, refParameters);
                            result = SerializeObject(jObj);

                            DataExchange.ProcessTransfer_Load(listTransfer, jObj, ref transferGlobal, ref transferSingle);
                            break;
                        default:
                            // Add、Edit、Del函式Resutn一般字串success、fail、other
                            var jObj2 = new Newtonsoft.Json.Linq.JObject();
                            try
                            {
                                jObj2.Add("ReturnValue", Newtonsoft.Json.Linq.JToken.Parse(SerializeObject(Convert.ChangeType(miResult, mi.ReturnType))));
                            }
                            catch (Exception ex)
                            {
                                if (miResult == null)
                                {
                                    jObj2.Add("ReturnValue", "");
                                }
                                else
                                {
                                    jObj2.Add("ReturnValue", miResult.ToString());
                                }

                            }

                            DataExchange.PorcessRef(ref jObj2, parameters, refParameters);
                            result = SerializeObject(jObj2);

                            // 處理傳遞引數
                            DataExchange.ProcessTransfer(listTransfer, jObj2, ref transferGlobal, ref transferSingle);
                            break;
                    }
                }

                // 紀錄Log
                try
                {
                    if (logFlag)
                    {
                        string strResult;
                        if (miResult == null)
                        {
                            strResult = "";
                        }
                        else
                        {
                            strResult = miResult.ToString();
                        }
                        var parName = default(string);
                        var parVal = default(string);
                        string desc = strResult == "fail" ? methodName + "Fail," : methodName + ",";
                        foreach (string key in argsIgnoreCase.Keys)
                        {
                            if (string.IsNullOrEmpty(parName))
                            {
                                parName = key;
                                parVal = argsIgnoreCase[key].ToString();
                            }
                            if (argsIgnoreCase[key] == null)
                            {
                                desc += key + ":" + " ";
                            }
                            else
                            {
                                desc += key + ":" + argsIgnoreCase[key].ToString() + " ";
                            }
                        }

                        if (strResult == "fail")
                        {
                            objSYS.AddErrorLog("MESws", userNo, parName, parVal, DateTime.Now, desc, ComputerName: computerName);
                        }
                        else
                        {
                            objSYS.AddEventLog("MESws", userNo, parName, parVal, DateTime.Now, desc, ComputerName: computerName);
                        }
                    }
                }
                catch (Exception ex)
                {

                }
                // 2020/07/30 雋辰,增加log
                try
                {
                    string parMsg = "";
                    string val = "";
                    if (!(copyParameters == null))
                    {
                        for (int i = 0, loopTo3 = copyParameters.Length - 1; i <= loopTo3; i++)
                        {
                            if (copyParameters[i] == null)
                            {
                                val = "parameter is Null";
                            }
                            else
                            {
                                val = (copyParameters[i].GetType().Equals(typeof(DataTable)) ? SerializeObject(copyParameters[i]) : copyParameters[i].ToString());
                            }
                            parMsg += string.Format("{0}:{1}{2}", miParameters[i].Name, val, Constants.vbNewLine);
                        }
                    }
                    var strBulder = new System.Text.StringBuilder();
                    strBulder.AppendLine("Method:" + method);
                    strBulder.AppendLine("Parameter:");
                    strBulder.Append(parMsg);
                    strBulder.Append("Response:" + result);
                    Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Info, null);
                }
                catch (Exception ex)
                {
                    Log.WriteLog("WriteLog fail.", iMESLog.iMESLogLevel.Warn, ex);
                }
            }
            catch (Exception ex)
            {
                if (!(ex.InnerException == null) && ex.InnerException is iMESException.MESException)
                    ex = ex.InnerException;

                // 紀錄Log
                try
                {
                    if (logFlag)
                    {
                        var parName = default(string);
                        var parVal = default(string);
                        string desc = methodName + "Fail,";
                        string descException;
                        foreach (string key in argsIgnoreCase.Keys)
                        {
                            if (string.IsNullOrEmpty(parName))
                            {
                                parName = key;
                                parVal = argsIgnoreCase[key].ToString();
                            }
                            desc += key + ":" + argsIgnoreCase[key].ToString() + " ";
                        }
                        if (ex is iMESException.MESException)
                        {
                            string argcode = Convert.ToString((ex as iMESException.MESException).ErrorCode);
                            string argsysmsg = TranslateMsg(ex.Message, language, strResourceDir);
                            descException = CombineXMLException(argcode, argsysmsg, desc, ex.StackTrace);
                        }
                        else
                        {
                            string argsysmsg1 = ex.Message;
                            descException = CombineXMLException(defWSErrCode, argsysmsg1, desc, ex.StackTrace);
                        }
                        objSYS.AddErrorLog("MESws", userNo, parName, parVal, DateTime.Now, descException, ComputerName: computerName);
                    }
                }
                catch (Exception ex2)
                {

                }
                // 2020/07/30 雋辰,增加log
                try
                {
                    string parMsg = "";
                    string val = "";
                    if (!(copyParameters == null))
                    {
                        for (int i = 0, loopTo = copyParameters.Length - 1; i <= loopTo; i++)
                        {
                            if (copyParameters[i] == null)
                            {
                                val = "parameter is Null";
                            }
                            else
                            {
                                val = copyParameters[i].GetType().Equals(typeof(DataTable)) ? SerializeObject(copyParameters[i]) : copyParameters[i].ToString();
                            }
                            parMsg += string.Format("{0}:{1}{2}", miParameters[i].Name, val, Constants.vbNewLine);
                        }
                    }
                    var strBulder = new System.Text.StringBuilder();
                    strBulder.AppendLine("Method:" + method);
                    strBulder.AppendLine("Parameter:");
                    strBulder.Append(parMsg);
                    Log.WriteLog(strBulder.ToString(), iMESLog.iMESLogLevel.Error, ex);
                }
                catch (Exception ex2)
                {
                    Log.WriteLog("WriteLog Err fail:" + methodName, iMESLog.iMESLogLevel.Warn, ex);
                }
                throw;
            }
            finally
            {
                objSYS.Dispose();
            }

            // 79915:  效能監控擴充 2020/10/20 效能監控 Edison
            // ==============================================79915 Start ==============================================
            stpCostTime.Stop();
            datEndTime = DateTime.Now;

            if (!string.IsNullOrEmpty(dllName) && !string.IsNullOrEmpty(csName) && !string.IsNullOrEmpty(methodName))
            {

                long Duration = 0L;
                string InXml;
                if (string.IsNullOrEmpty(userNo))
                    userNo = "N/A";
                if (string.IsNullOrEmpty(computerName))
                    computerName = "N/A";

                var XmlDoc = new System.Xml.XmlDocument();

                try
                {

                    // 取出開始到結束的執行時間(毫秒為單位).
                    Duration = stpCostTime.ElapsedMilliseconds;
                }

                catch (Exception ex)
                {
                }

                finally
                {
                    XmlDoc = null;
                }


                int intChkDurationLog = -1;

                using (var objSYSLog = new kcSYS.clsSYSUserLog())
                {
                    try
                    {
                        intChkDurationLog = objSYSLog.ChkDurationLog(dllName, csName, methodName);
                    }
                    catch (Exception ex)
                    {
                        objSYSLog.AddErrorLog("wsInvoke.Invoke", userNo, "ChkDurationLog", method, datEndTime, ex.Message, ComputerName: computerName);
                    }

                    // 記錄Log
                    if (intChkDurationLog == 0)
                    {
                        try
                        {
                            objSYSLog.AddMESTransactionLog(userNo, dllName, csName, methodName, datStartTime, datEndTime, Duration, computerName);
                        }
                        catch (Exception ex)
                        {
                            objSYSLog.AddErrorLog("wsInvoke.Invoke", userNo, "AddMESTransactionLog", method, datEndTime, ex.Message, ComputerName: computerName);
                        }
                    }

                }

            }
            // ==============================================79915 End  ==============================================

            return result;

        }


        /// <summary>
        /// 2019/03/05 OwenLiu, 與EAI一致的簡易呼叫方式
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        [WebMethod(Description = "EnableSession, Invoke Web Service Resolved json", EnableSession = true)]
        public string invokeSrv_Session_plainjson(string uri, string content)
        {

            var result = default(object);
            string strResponse = "";
            string strMessage = "";
            string method = "";
            string strClassName = "";
            string strMethodName = "";
            string strComponent = "";
            string[] aryTemp;
            string typeName;
            Type t;
            MethodInfo mi;
            Type[] argumentTypes;
            ConstructorInfo ctor;
            object obj;
            string strSendTime = "";
            var ometadata = new Dictionary<string, string>();
            var ocontent = new Dictionary<string, string>();
            var oResponseMsg = new iMES_ResponseMessage();
            string strlanguagemode = "";

            do
            {
                try
                {
                    if (uri == null || string.IsNullOrEmpty(uri.Trim()) || string.IsNullOrEmpty(uri))
                    {
                        break;
                    }

                    if (content == null || string.IsNullOrEmpty(content.Trim()) || string.IsNullOrEmpty(content))
                    {
                        // 2019/03/25 OwenLiu, 如果傳入的content是空的，把uri的內容指定給content
                        content = uri;
                    }
                    else
                    {
                        ocontent = DeserializeObject<Dictionary<string, string>>(content);
                        if (ocontent.Count.Equals(0))
                        {
                            content = uri;
                        }
                    }

                    object argobjSource = DateTime.Now;
                    strSendTime = funTransVarFormat(argobjSource, "yyyy/MM/dd HH:mm:ss");

                    try
                    {
                        ometadata = DeserializeObject<Dictionary<string, string>>(uri);
                    }
                    catch (Exception ex)
                    {
                        ometadata.Add("method", uri);
                        ometadata.Add("languagemode", "en");
                    }

                    method = ometadata["method"];
                    aryTemp = method.Split('.');

                    if (aryTemp.Length < 2 || aryTemp.Length > 3)
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    if (aryTemp.Length == 2)
                    {
                        strComponent = "wsSTD.dll";
                        strClassName = aryTemp[0];
                        strMethodName = aryTemp[1];
                    }
                    else if (aryTemp.Length == 3 && aryTemp[1].StartsWith("ws") == false)  // 2017-06-09, Joe, 不透過ws直接Call kc/tc/ud
                    {
                        // 前端傳入：kcXXX.clsXXX.AddXXXXX
                        strComponent = aryTemp[0] + ".dll";   // dll name
                        strClassName = aryTemp[1];   // class name
                        strMethodName = aryTemp[2];  // function name
                    }
                    else
                    {
                        strComponent = "ws" + aryTemp[0] + ".dll";
                        strClassName = aryTemp[1];
                        strMethodName = aryTemp[2];
                    }

                    if (string.IsNullOrEmpty(strComponent) || string.IsNullOrEmpty(strClassName) || string.IsNullOrEmpty(strMethodName))
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    string strAppBase = AppDomain.CurrentDomain.BaseDirectory;
                    string strFilePath = strAppBase.TrimEnd('\\') + @"\bin\" + strComponent;
                    var mainAssembly = Assembly.LoadFrom(strFilePath);

                    try
                    {
                        t = mainAssembly.GetType(mainAssembly.GetName().Name + "." + strClassName, true, true);
                    }
                    catch (Exception ex)
                    {
                        throw new iMESException.MESException("0000-003000", "WebService: " + strClassName + " [%LOAD FAIL%]!" + Constants.vbCrLf + ex.Message);
                    }

                    argumentTypes = Type.EmptyTypes;
                    ctor = t.GetConstructor(argumentTypes);
                    obj = ctor.Invoke(new object[] { });
                    mi = t.GetMethod(strMethodName);

                    try
                    {
                        result = mi.Invoke(obj, new object[] { uri, content });
                    }
                    catch (Exception ex)
                    {
                        if (ex.InnerException == null)
                        {
                            strMessage = ex.Message;
                        }
                        else
                        {
                            strMessage = ex.InnerException.Message;
                        }
                        throw new iMESException.MESException("0000-003000", strClassName + "." + strMethodName + " [%INVOKE FAIL%]!" + Constants.vbCrLf + strMessage);
                    }
                }

                catch (iMESException.MESException ex)
                {
                    if (ex.InnerException == null)
                    {
                        oResponseMsg.code = Convert.ToString(ex.ErrorCode);
                        oResponseMsg.exception = "invokeSrv_Session_plainjson fail;" + ex.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    else
                    {
                        oResponseMsg.code = Convert.ToString(ex.ErrorCode);
                        oResponseMsg.exception = "invokeSrv_Session_plainjson fail;" + ex.InnerException.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    result = oResponseMsg.CombineRsponseMessage(oResponseMsg, strlanguagemode, strResourceDir);
                }
                catch (Exception ex)
                {
                    if (ex.InnerException == null)
                    {
                        oResponseMsg.code = defWSErrCode;
                        oResponseMsg.exception = "invokeSrv_Session_plainjson fail;" + ex.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    else
                    {
                        oResponseMsg.code = defWSErrCode;
                        oResponseMsg.exception = "invokeSrv_Session_plainjson fail;" + ex.InnerException.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    result = oResponseMsg.CombineRsponseMessage(oResponseMsg, strlanguagemode, strResourceDir);
                }
                finally
                {

                    oResponseMsg = null;
                }
            }
            while (false);

            return Convert.ToString(result);

        }

        /// <summary>
        /// 2019/03/05 OwenLiu, 與EAI一致的簡易呼叫方式
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        [WebMethod(Description = "Invoke Web Service Resolved json")]
        public string invokeSrv_plainjson(string uri, string content)
        {

            var result = default(object);
            string strResponse = "";
            string strMessage = "";
            string method = "";
            string strClassName = "";
            string strMethodName = "";
            string strComponent = "";
            string[] aryTemp;
            string typeName;
            Type t;
            MethodInfo mi;
            Type[] argumentTypes;
            ConstructorInfo ctor;
            object obj;
            string strSendTime = "";
            var ometadata = new Dictionary<string, string>();
            var ocontent = new Dictionary<string, string>();
            var oResponseMsg = new iMES_ResponseMessage();
            string strlanguagemode = "";

            do
            {
                try
                {
                    if (uri == null || string.IsNullOrEmpty(uri.Trim()) || string.IsNullOrEmpty(uri))
                    {
                        break;
                    }
                    if (content == null || string.IsNullOrEmpty(content.Trim()) || string.IsNullOrEmpty(content))
                    {
                        // 2019/03/25 OwenLiu, 如果傳入的content是空的，把uri的內容指定給content
                        content = uri;
                    }
                    else
                    {
                        ocontent = DeserializeObject<Dictionary<string, string>>(content);
                        if (ocontent.Count.Equals(0))
                        {
                            content = uri;
                        }
                    }

                    object argobjSource = DateTime.Now;
                    strSendTime = funTransVarFormat(argobjSource, "yyyy/MM/dd HH:mm:ss");


                    try
                    {
                        ometadata = DeserializeObject<Dictionary<string, string>>(uri);
                    }
                    catch (Exception ex)
                    {
                        ometadata.Add("method", uri);
                        ometadata.Add("languagemode", "en");
                    }


                    method = ometadata["method"];
                    aryTemp = method.Split('.');

                    if (aryTemp.Length < 2 || aryTemp.Length > 3)
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    if (aryTemp.Length == 2)
                    {
                        strComponent = "wsSTD.dll";
                        strClassName = aryTemp[0];
                        strMethodName = aryTemp[1];
                    }
                    else if (aryTemp.Length == 3 && aryTemp[1].StartsWith("ws") == false)  // 2017-06-09, Joe, 不透過ws直接Call kc/tc/ud
                    {
                        // 前端傳入：kcXXX.clsXXX.AddXXXXX
                        strComponent = aryTemp[0] + ".dll";   // dll name
                        strClassName = aryTemp[1];   // class name
                        strMethodName = aryTemp[2];  // function name
                    }
                    else
                    {
                        strComponent = "ws" + aryTemp[0] + ".dll";
                        strClassName = aryTemp[1];
                        strMethodName = aryTemp[2];
                    }

                    if (string.IsNullOrEmpty(strComponent) || string.IsNullOrEmpty(strClassName) || string.IsNullOrEmpty(strMethodName))
                    {
                        throw new iMESException.MESException("0000-003000", "Invoke method(" + method + ") [%FORMAT ERROR%], [%FOR EXAMPLE%] wsENT.LoadCustomerBasis [%OR%] LED.wsENT.LoadCustomerBasis!");
                    }

                    string strAppBase = AppDomain.CurrentDomain.BaseDirectory;
                    string strFilePath = strAppBase.TrimEnd('\\') + @"\bin\" + strComponent;
                    var mainAssembly = Assembly.LoadFrom(strFilePath);

                    try
                    {
                        t = mainAssembly.GetType(mainAssembly.GetName().Name + "." + strClassName, true, true);
                    }
                    catch (Exception ex)
                    {
                        throw new iMESException.MESException("0000-003000", "WebService: " + strClassName + " [%LOAD FAIL%]!" + Constants.vbCrLf + ex.Message);
                    }

                    argumentTypes = Type.EmptyTypes;
                    ctor = t.GetConstructor(argumentTypes);
                    obj = ctor.Invoke(new object[] { });
                    mi = t.GetMethod(strMethodName);
                    object intParameterLength = mi.GetParameters().GetLength(0);

                    try
                    {
                        if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(intParameterLength, 1, false)))
                        {
                            result = mi.Invoke(obj, new object[] { content });
                        }
                        else if (Convert.ToBoolean(Operators.ConditionalCompareObjectEqual(intParameterLength, 2, false)))
                        {
                            result = mi.Invoke(obj, new object[] { uri, content });
                        }
                    }

                    catch (Exception ex)
                    {
                        if (ex.InnerException == null)
                        {
                            strMessage = ex.Message;
                        }
                        else
                        {
                            strMessage = ex.InnerException.Message;
                        }
                        throw new iMESException.MESException("0000-003000", strClassName + "." + strMethodName + " [%INVOKE FAIL%]!" + Constants.vbCrLf + strMessage);
                    }
                }

                catch (iMESException.MESException ex)
                {
                    if (ex.InnerException == null)
                    {
                        oResponseMsg.code = Convert.ToString(ex.ErrorCode);
                        oResponseMsg.exception = "invokeSrv_plainjson fail;" + ex.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    else
                    {
                        oResponseMsg.code = Convert.ToString(ex.ErrorCode);
                        oResponseMsg.exception = "invokeSrv_plainjson fail;" + ex.InnerException.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    result = oResponseMsg.CombineRsponseMessage(oResponseMsg, strlanguagemode, strResourceDir);
                }
                catch (Exception ex)
                {
                    if (ex.InnerException == null)
                    {
                        oResponseMsg.code = defWSErrCode;
                        oResponseMsg.exception = "invokeSrv_plainjson fail;" + ex.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    else
                    {
                        oResponseMsg.code = defWSErrCode;
                        oResponseMsg.exception = "invokeSrv_plainjson fail;" + ex.InnerException.Message;
                        oResponseMsg.stacktrace = ex.StackTrace;
                    }
                    result = oResponseMsg.CombineRsponseMessage(oResponseMsg, strlanguagemode, strResourceDir);
                }
                finally
                {

                    oResponseMsg = null;
                }
            }
            while (false);

            return Convert.ToString(result);

        }

        /// <summary>
        /// 2020/08/28 雋辰,檢查、更新sesstion
        /// </summary>
        /// <param name="sessionId">session編號</param>
        private void CheckSession(string sessionId)
        {
            var XmlDoc = new System.Xml.XmlDocument();
            var dsLogin = new DataSet();
            string xmlSchema;
            string xmlData;

            var kcLogin = new iMESUserManager.clsUSRLoginInfo();

            // 測試時不會有Session,所以測試不檢查
            if (string.IsNullOrEmpty(sessionId))
                return;

            try
            {
                // 檢查session
                string outXML = kcLogin.LoadLoginInfo(sessionId);

                XmlDoc.LoadXml(outXML);
                xmlSchema = XmlDoc.SelectSingleNode("loadlogininfo").SelectSingleNode("schema").InnerXml;
                if (!string.IsNullOrEmpty(xmlSchema))
                {
                    // 將XML讀入String Reader object中,因為Dataset讀入XML時必須透過String Reader物件
                    using (var tmpStringReader = new StringReader(xmlSchema))
                    {
                        dsLogin.ReadXmlSchema(tmpStringReader);
                    }
                }
                // 取出Data
                xmlData = XmlDoc.SelectSingleNode("loadlogininfo").SelectSingleNode("value").InnerXml;
                if (!string.IsNullOrEmpty(xmlData))
                {
                    using (var tmpStringReader = new StringReader(xmlData))
                    {
                        dsLogin.ReadXml(tmpStringReader, XmlReadMode.InferSchema);
                    }
                }

                if (dsLogin.Tables[0].Rows.Count <= 0)
                {
                    throw new iMESException.MESException("0000-202414", "[%Disconnect%]");
                }

                // 更新session
                kcLogin.RefreshIdleTime(sessionId);
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        #endregion

        #region GuardServer
        [WebMethod(Description = "return hysical directory")]
        public object Invoke_GuardServer_Process()
        {
            return HttpContext.Current.Server.MapPath(".");
        }
        #endregion

    }
}