using System; using System.Data; using System.Deployment.Application; using System.Diagnostics; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.ServiceProcess; using System.Xml; using Microsoft.VisualBasic; using Microsoft.VisualBasic.CompilerServices; using static iMESCore.Base.iMESConst; using static iMESCore.Base.iMESComXML; using static iMESCore.Base.iMESComSubroutine; namespace AutoRunService { public partial class AutoRunService : ServiceBase { // 2016/06/23 YF, 改呼叫wsInvoke private string tblJobQueue, tblJob; private int intMaxRunningJobCount = modAutoRun.gIntMaxRunningJobCount; // 2017/12/26 OwenLiu, mantis:0043439, AutoRunService 問題調整 // 2014/06/25 YF, 記錄JOB的執行狀況 private Collection CollectionJob = new Collection(); // 取回JOB LIST 到 JOB QUEUE的時間間隔(單位:秒) '20211015 13871,修正為*1000才是秒 private int MonitorjoblistDuration = (int)Math.Round(Conversions.ToDouble(modWIN.GetAppSettings("MonitorjoblistDuration")) * 1000d); // 到JOB QUEUE 檢查是否有要執行的job的時間間隔(單位:秒) '20211015 13871,修正為*1000才是秒 private int MonitorQueueDuration = (int)Math.Round(Conversions.ToDouble(modWIN.GetAppSettings("MonitorQueueDuration")) * 1000d); public AutoRunService() { InitializeComponent(); } protected override void OnStart(string[] args) { var currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledException += CurrentDomain_UnhandledException; // 在此加入啟動服務的程式碼。這個方法必須設定已啟動的 // 事項,否則可能導致服務無法工作。 funWriteTxtFile("Service Starting."); // 2012/10/05, Aaron, 啟動時先刪除資料庫中上次執行的殘留JobQueue funDelMesAutoRunQueue(); // 啟動時先載入Job List及Table架構 funLoadAutoRunJob_All(); // 每隔n秒鐘, 取回一次JOB LIST 到 JOB QUEUE TimerCheckJobList.Interval = MonitorjoblistDuration; TimerCheckJobList.Enabled = true; // 每隔n秒鐘,到 JOB QUEUE 檢查是否有要執行的 TimerCheckQueue.Interval = MonitorQueueDuration; TimerCheckQueue.Enabled = true; modAutoRun.gIntCurrentJobCount = 0; funWriteTxtFile("Service Started."); } protected override void OnStop() { // 在此加入停止服務所需執行的終止程式碼。 modAutoRun.dsJob.Dispose(); modAutoRun.dsJobQueue.Dispose(); TimerCheckJobList.Enabled = false; TimerCheckQueue.Enabled = false; funWriteTxtFile("Service Stopped."); } /// /// 取出近期的Job放入JobQueue中, /// /// /// /// private void TimerCheckJobList_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // funWriteTxtFile("Running CheckJobList...") TimerCheckJobList.Enabled = false; // *****取回最近要執行的Jobs, 放入JobQueue中 funGetJob2Queue(); // *****平分近8分的工作 TimerCheckJobList.Enabled = true; } /// /// 定期檢查JobQueue是否有工作預定執行之動作, /// /// /// /// private void TimerCheckQueue_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // funWriteTxtFile("Running CheckQueue...") // 若未達到最大同時執行工作數目之限制時 if (modAutoRun.gIntCurrentJobCount < intMaxRunningJobCount) { TimerCheckQueue.Enabled = false; do { try { int intTmp; var strJOB = new string[3]; DateTime dateTmp; int intTmp2; string strServerName; // *****從JobQueue中取回資料,存成 DataSet funReBind(); // 2017/12/26 OwenLiu, mantis:0043439, AutoRunService 問題調整 // 2014/06/25 YF, JobQueue物件不存在則跳離 if (modAutoRun.dsJobQueue.Tables[tblJobQueue] == null) { break; } // 2014/06/25 YF, 將tblJobQueue內Running的Job與CollectionJob做比對, 來判斷Job是否已死在Queue內 // CollectionJob內若還有此JobNo, 則表示該Job還在執行中, 若沒有則表示Job已死 CheckJobIsDead(); // '*****檢查是否有需要執行的job, 包含沒有設定ServiceStation或ServiceStation為ME的Job DataRow[] dr = modAutoRun.dsJobQueue.Tables[tblJobQueue].Select("(ServerName is null Or ServerName='' Or ServerName='" + System.Windows.Forms.SystemInformation.ComputerName.ToString().ToUpper() + "') and STATUS='Standby'"); // 如果有則處理它們 var loopTo = dr.Length - 1; for (intTmp = 0; intTmp <= loopTo; intTmp++) { // 若未達到最大同時執行工作數目之限制時 if (modAutoRun.gIntCurrentJobCount < intMaxRunningJobCount) { dateTmp = Conversions.ToDate(dr[intTmp][2]); // ..........判斷此job是否執行時間到 if (dateTmp <= DateTime.Now) { strJOB[0] = Conversions.ToString(dr[intTmp][0]); strJOB[1] = Conversions.ToString(dr[intTmp][5]); // ..............再檢查一次,判斷此job是否尚未有人執行 strServerName = funLoadAutoRunServerName(strJOB[0]); if ((strServerName ?? "") != defString) { if (string.IsNullOrEmpty(strServerName) || string.IsNullOrEmpty(strServerName.Trim())) { intTmp2 = 1; // 尚未有主機登記要執行 } else if ((strServerName ?? "") == (System.Windows.Forms.SystemInformation.ComputerName ?? "")) { intTmp2 = 1; // 本主機自行登記要執行 } else { intTmp2 = 0; } // 已經有其他機器登記要執行 // 尚未有主機登記要執行或本主機自行登記要執行 if (intTmp2 == 1) { // 寫入註明自己正要執行 funUpdateAutoRunQueue(System.Windows.Forms.SystemInformation.ComputerName, strJOB[0], defString); // ..........再取一次,判斷ServerName是否為自己 strServerName = funLoadAutoRunServerName(strJOB[0]); if ((strServerName ?? "") != defString) { if ((strServerName ?? "") == (System.Windows.Forms.SystemInformation.ComputerName ?? "")) { modAutoRun.gIntCurrentJobCount = modAutoRun.gIntCurrentJobCount + 1; // 建立傳入執行緒之參數物件 var objJobData = new modAutoRun.SomeStateType(); objJobData.SomeState(strJOB[0], strJOB[1]); // 開始執行 if (System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(funProcessJob), objJobData) == false) { // MsgBox("Thread fail.") } } } // ...........If DataReader.Read Then } // .............If intTmp2 = 1 Then } // ...............判斷是否尚未有人執行 If DataReader.Read Then } // .........判斷是否執行時間到 If dateTmp <= Now Then } // ...........If gIntCurrentJobCount <= intMaxRunningJobCount Then } } catch (Exception e1) { funWriteTxtFile("TimerCheckQueue Error : " + e1.Message); funWriteToAnEventLog("TimerCheckQueue Error : " + e1.Message, EventLogEntryType.Error, 9000); } finally { } } while (false); TimerCheckQueue.Enabled = true; } // 'Call funReBind() } /// /// 將執行的Log紀錄在文字檔(AutoRunWS_Log.txt)中 /// /// /// /// private int funWriteTxtFile(string WriteTxt) { int funWriteTxtFileRet = default(int); funWriteTxtFileRet = -1; try { if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + @"\Log")) { Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + @"\Log"); } var fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + @"\Log\AutoRunWS_Log_" + Strings.Format(DateTime.Now, "yyyyMMdd") + ".txt", FileMode.OpenOrCreate, FileAccess.ReadWrite); var w = new StreamWriter(fs); w.BaseStream.Seek(0L, SeekOrigin.End); w.WriteLine(Strings.Format(DateTime.Now, "yyyy/MM/dd HH:mm:ss") + " " + WriteTxt); w.Close(); fs.Close(); funWriteTxtFileRet = 0; } catch (Exception e1) { } return funWriteTxtFileRet; } private void funWriteToAnEventLog(string sEvent, EventLogEntryType sEventType = EventLogEntryType.Information, int sEventID = 0) { string sSource = "MES AutoRun Service"; string sLog = "Application"; try { if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource, sLog); EventLog.WriteEntry(sSource, sEvent, sEventType, sEventID); } catch (Exception ex) { } } /// /// 重新載入JobQueue資料 /// /// /// private int funReBind() { // //Web Service相關變數 var XmlDoc = new XmlDocument(); StringReader tmpStringReader; string InXml, OutXml, strIdentity, strParameter, XmlData, XmlSchema; // 先判斷是否dataset中已有equipmenttype之datatable,若有,需先remove否則會有錯誤 if (!(modAutoRun.dsJobQueue.Tables[tblJobQueue] == null)) { modAutoRun.dsJobQueue.Tables.Remove(tblJobQueue); } // 組InXml的字串 string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); strParameter = ""; InXml = CombineXMLRequest(strIdentity, strParameter); try { // OutXml = wsAUT.LoadMesAutoRunQueue(InXml) OutXml = modAutoRun.InvokeSrv("wsAUT.LoadMesAutoRunQueue", InXml); XmlDoc = new XmlDocument(); // 利用XmlDoc物件處理ReturnValue XmlDoc.LoadXml(OutXml); if (chkExecutionSuccess(XmlDoc)) { tblJobQueue = XmlDoc.GetElementsByTagName("returnvalue").Item(0).SelectNodes("loadmesautorunqueue").Item(0).SelectNodes("name").Item(0).InnerXml; // 取出Schema,dataset讀取Schema可防止Null Field及DateTime的問題 XmlSchema = XmlDoc.DocumentElement.GetElementsByTagName("loadmesautorunqueue").Item(0).SelectNodes("schema").Item(0).InnerXml; if (!string.IsNullOrEmpty(XmlSchema)) { // 將XML讀入String Reader object中,因為Dataset讀入XML時必須透過String Reader物件 tmpStringReader = new StringReader(XmlSchema); modAutoRun.dsJobQueue.ReadXmlSchema(tmpStringReader); tmpStringReader.Close(); } // 取出Data XmlData = XmlDoc.DocumentElement.GetElementsByTagName("loadmesautorunqueue").Item(0).SelectNodes("value").Item(0).InnerXml; if (!string.IsNullOrEmpty(XmlData)) { tmpStringReader = new StringReader(XmlData); modAutoRun.dsJobQueue.ReadXml(tmpStringReader); tmpStringReader.Close(); } } else { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } } catch (Exception e1) { funWriteTxtFile("funReBind Error : " + e1.Message); funWriteToAnEventLog("funReBind Error : " + e1.Message, EventLogEntryType.Error, 9000); } return default(int); } /// /// 取出近期的Job放入JobQueue中 /// /// public void funGetJob2Queue() { // //Web Service相關變數 var XmlDoc = new XmlDocument(); string InXml, OutXml, strIdentity, strParameter; // 組InXml的字串 string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); strParameter = ""; InXml = CombineXMLRequest(strIdentity, strParameter); try { // OutXml = wsAUT.GetJob2Queue(InXml) OutXml = modAutoRun.InvokeSrv("wsAUT.GetJob2Queue", InXml); // 利用XmlDoc物件處理ReturnValue XmlDoc.LoadXml(OutXml); if (!chkExecutionSuccess(XmlDoc)) { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } } catch (Exception e1) { funWriteTxtFile("funGetJob2Queue Error : " + e1.Message); funWriteToAnEventLog("funGetJob2Queue Error : " + e1.Message, EventLogEntryType.Error, 9000); } } /// /// 取出ServerName /// /// /// /// private string funLoadAutoRunServerName(string JobNo) { string funLoadAutoRunServerNameRet = default(string); // 判斷此job是否尚未有人執行 // 判斷ServerName是否為自己(本機) funLoadAutoRunServerNameRet = defString; // //Web Service相關變數 var XmlDoc = new XmlDocument(); string InXml, OutXml, strIdentity, strParameter; // 組InXml的字串 strParameter = ""; string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); string argvalue_name = "jobno"; string argname = "JobNo"; string argtype = "String"; string argdesc = ""; strParameter = CombineXMLParameter(argvalue_name, argname, argtype, JobNo, argdesc); InXml = CombineXMLRequest(strIdentity, strParameter); try { // OutXml = wsAUT.LoadMesAutoRunQueue(InXml) OutXml = modAutoRun.InvokeSrv("wsAUT.LoadMesAutoRunQueue", InXml); XmlDoc.LoadXml(OutXml); if (chkExecutionSuccess(XmlDoc)) { // 取出CPN if (XmlDoc.GetElementsByTagName("ServerName".ToUpper()).Count > 0) { string serverNameTmp = XmlDoc.GetElementsByTagName("ServerName".ToUpper()).Item(0).InnerXml.ToString(); funLoadAutoRunServerNameRet = CUnInput(serverNameTmp); } else { funLoadAutoRunServerNameRet = ""; } } else { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } XmlDoc = null; } catch (Exception e1) { funWriteTxtFile("funLoadAutoRunServerName (JobNo : " + JobNo + ") Error : " + e1.Message); funWriteToAnEventLog("funLoadAutoRunServerName (JobNo : " + JobNo + ") Error : " + e1.Message, EventLogEntryType.Error, 9000); } return funLoadAutoRunServerNameRet; } private int funUpdateAutoRunQueue(string ServerName, string JobNo, string Status) { int funUpdateAutoRunQueueRet = default(int); // 寫入註明自己(本機)正要執行 funUpdateAutoRunQueueRet = -1; // //Web Service相關變數 var XmlDoc = new XmlDocument(); string InXml, OutXml, strIdentity, strParameter; try { // 將傳入參數組成XML字串 // 定義Identity string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); // 定義Parameter strParameter = string.Empty; strParameter = ""; if ((ServerName ?? "") != defString) { string argvalue_name = "servername"; string argname = "ServerName"; string argtype = "String"; string argdesc = ""; strParameter += CombineXMLParameter(argvalue_name, argname, argtype, ServerName, argdesc); } if ((JobNo ?? "") != defString) { string argvalue_name1 = "jobno"; string argname1 = "JobNo"; string argtype1 = "String"; string argdesc1 = ""; strParameter += CombineXMLParameter(argvalue_name1, argname1, argtype1, JobNo, argdesc1); } if ((Status ?? "") != defString) { string argvalue_name2 = "status"; string argname2 = "Status"; string argtype2 = "String"; string argdesc2 = ""; strParameter += CombineXMLParameter(argvalue_name2, argname2, argtype2, Status, argdesc2); } // request XML字串 InXml = CombineXMLRequest(strIdentity, strParameter); // OutXml = wsAUT.EditMesAutoRunQueue(InXml) OutXml = modAutoRun.InvokeSrv("wsAUT.EditMesAutoRunQueue", InXml); XmlDoc.LoadXml(OutXml); if (!chkExecutionSuccess(XmlDoc)) { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } funUpdateAutoRunQueueRet = 0; } catch (Exception e1) { // Throw New Exception("Unexpected Error. Update auto-run queue fails. " & e1.Message) funWriteTxtFile("funUpdateAutoRunQueue (JobNo : " + JobNo + ") Error : " + e1.Message); funWriteToAnEventLog("funUpdateAutoRunQueue (JobNo : " + JobNo + ") Error : " + e1.Message, EventLogEntryType.Error, 9000); } return funUpdateAutoRunQueueRet; } /// /// 取出Job參數設定 /// /// /// /// 2016/04/26 YF, 此Function的目的在取出要執行的JOB的參數, 故不要使用dsJob物件, 以避免各執行緒異動dsJob, 而造成 "DataTable 内部索引已损坏" 的錯誤 /// private int funLoadAutoRunJob(string JobNo, ref Collection colParameters) { // Dim dr As DataRow // //Web Service相關變數 var XmlDoc = new XmlDocument(); StringReader tmpStringReader; string InXml, OutXml, strIdentity, strParameter, XmlData, XmlSchema; // 先判斷是否dataset中已有datatable,若有,需先remove否則會有錯誤 // If Not IsNothing(dsJobQueue.Tables(tblJob)) Then // dsJobQueue.Tables.Remove(tblJob) // End If // 組InXml的字串 strParameter = ""; string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); string argvalue_name = "jobno"; string argname = "JobNo"; string argtype = "String"; string argdesc = ""; strParameter = CombineXMLParameter(argvalue_name, argname, argtype, JobNo, argdesc); InXml = CombineXMLRequest(strIdentity, strParameter); try { // OutXml = wsAUT.LoadMesAutoRunJob(InXml) OutXml = modAutoRun.InvokeSrv("wsAUT.LoadMesAutoRunJob", InXml); // 利用XmlDoc物件處理ReturnValue XmlDoc.LoadXml(OutXml); if (chkExecutionSuccess(XmlDoc)) { // 2017/12/26 OwenLiu, mantis:0043439, AutoRunService 問題調整 tblJob = XmlDoc.GetElementsByTagName("returnvalue").Item(0).SelectNodes("loadmesautorunjob").Item(0).SelectNodes("name").Item(0).InnerXml; // 2017/12/26 OwenLiu, mantis:0043439, AutoRunService 問題調整 lock (this) { if (modAutoRun.dsJob.Tables[tblJob] == null) { // 取出Schema,dataset讀取Schema可防止Null Field及DateTime的問題 XmlSchema = XmlDoc.DocumentElement.GetElementsByTagName("loadmesautorunjob").Item(0).SelectNodes("schema").Item(0).InnerXml; if (!string.IsNullOrEmpty(XmlSchema)) { // 將XML讀入String Reader object中,因為Dataset讀入XML時必須透過String Reader物件 tmpStringReader = new StringReader(XmlSchema); modAutoRun.dsJob.ReadXmlSchema(tmpStringReader); tmpStringReader.Close(); } } // 先刪除舊資料 DataRow[] drSel; drSel = modAutoRun.dsJob.Tables[tblJob].Select("JobNo = '" + JobNo + "'"); if (drSel.Length > 0) drSel[0].Delete(); // 取出Data XmlData = XmlDoc.DocumentElement.GetElementsByTagName("loadmesautorunjob").Item(0).SelectNodes("value").Item(0).InnerXml; if (!string.IsNullOrEmpty(XmlData)) { tmpStringReader = new StringReader(XmlData); modAutoRun.dsJob.ReadXml(tmpStringReader); tmpStringReader.Close(); } drSel = modAutoRun.dsJob.Tables[tblJob].Select("JobNo = '" + JobNo + "'"); if (drSel.Length > 0) { colParameters.Add(drSel[0]["Parameter01"].ToString(), "Parameter01"); colParameters.Add(drSel[0]["Parameter02"].ToString(), "Parameter02"); colParameters.Add(drSel[0]["Parameter03"].ToString(), "Parameter03"); colParameters.Add(drSel[0]["Parameter04"].ToString(), "Parameter04"); colParameters.Add(drSel[0]["Parameter05"].ToString(), "Parameter05"); colParameters.Add(drSel[0]["Parameter06"].ToString(), "Parameter06"); colParameters.Add(drSel[0]["Parameter07"].ToString(), "Parameter07"); colParameters.Add(drSel[0]["Parameter08"].ToString(), "Parameter08"); colParameters.Add(drSel[0]["Parameter09"].ToString(), "Parameter09"); colParameters.Add(drSel[0]["Parameter10"].ToString(), "Parameter10"); colParameters.Add(drSel[0]["EmailAddress"].ToString(), "EmailAddress"); } } } else { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } } catch (Exception e1) { funWriteTxtFile("funLoadAutoRunJob (JobNo : " + JobNo + ") Error : " + e1.Message); funWriteToAnEventLog("funLoadAutoRunJob (JobNo : " + JobNo + ") Error : " + e1.Message, EventLogEntryType.Error, 9000); } return default(int); } private void funLoadAutoRunJob_All() { // Dim dr As DataRow // //Web Service相關變數 var XmlDoc = new XmlDocument(); StringReader tmpStringReader; string InXml, OutXml, strIdentity, strParameter, XmlData, XmlSchema; // 先判斷是否dataset中已有datatable,若有,需先remove否則會有錯誤 if (!(modAutoRun.dsJob.Tables[tblJob] == null)) { modAutoRun.dsJob.Tables.Remove(tblJob); } // 組InXml的字串 string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); strParameter = ""; InXml = CombineXMLRequest(strIdentity, strParameter); try { // OutXml = wsAUT.LoadMesAutoRunJob(InXml) OutXml = modAutoRun.InvokeSrv("wsAUT.LoadMesAutoRunJob", InXml); // 利用XmlDoc物件處理ReturnValue XmlDoc.LoadXml(OutXml); if (chkExecutionSuccess(XmlDoc)) { tblJob = XmlDoc.GetElementsByTagName("returnvalue").Item(0).SelectNodes("loadmesautorunjob").Item(0).SelectNodes("name").Item(0).InnerXml; // 取出Schema,dataset讀取Schema可防止Null Field及DateTime的問題 XmlSchema = XmlDoc.DocumentElement.GetElementsByTagName("loadmesautorunjob").Item(0).SelectNodes("schema").Item(0).InnerXml; if (!string.IsNullOrEmpty(XmlSchema)) { // 將XML讀入String Reader object中,因為Dataset讀入XML時必須透過String Reader物件 tmpStringReader = new StringReader(XmlSchema); modAutoRun.dsJob.ReadXmlSchema(tmpStringReader); tmpStringReader.Close(); } // 取出Data XmlData = XmlDoc.DocumentElement.GetElementsByTagName("loadmesautorunjob").Item(0).SelectNodes("value").Item(0).InnerXml; if (!string.IsNullOrEmpty(XmlData)) { tmpStringReader = new StringReader(XmlData); modAutoRun.dsJob.ReadXml(tmpStringReader); tmpStringReader.Close(); } } else { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } } catch (Exception e1) { funWriteTxtFile("funLoadAutoRunJob_All Error : " + e1.Message); funWriteToAnEventLog("funLoadAutoRunJob_All Error : " + e1.Message, EventLogEntryType.Error, 9000); } } /// /// 執行設定的Job /// /// /// public void funProcessJob(object State) { modAutoRun.SomeStateType strJob = (modAutoRun.SomeStateType)State; string strJobNo = strJob.strJobNo; string strJobName = strJob.strCommandName; var StartTime = DateTime.Now; string strStatus = "Fail"; // 回傳狀況先設定為Fail string strReturnMsg = ""; string strMemo = ""; string errorCode = "0000-999999"; try { funWriteTxtFile("JobNo : " + strJobNo + ", Running."); // 2017/12/26 OwenLiu, mantis:0043439, AutoRunService 問題調整 // 2014/06/25 YF, Job Running if (CollectionJob.Contains(strJobNo)) { CollectionJob.Remove(strJobNo); } CollectionJob.Add(1, strJobNo); // 1. 註明正在執行 funUpdateAutoRunQueue(defString, strJobNo, "Running"); // 2. 取出tblMESAutoRunJob的參數(Parameter1~Parameter5) var colParameters = new Collection(); colParameters.Add(strJobNo, "JobNo"); funLoadAutoRunJob(strJobNo, ref colParameters); // 3. 引用AutoRunLib.dll, 不加入參考 ---- string strAppBase = AppDomain.CurrentDomain.BaseDirectory; string strFilePath; // 判斷是否是使用ClickOnce if (ApplicationDeployment.IsNetworkDeployed) { // ClickOnce架構下將strAppBase改指回Smart Client var tempUri = ApplicationDeployment.CurrentDeployment.UpdateLocation; strAppBase = tempUri.ToString().Replace("/ClickOnce/MESSeries.application", ""); } if (Strings.Mid(strAppBase, 1, 4) == "http") { strFilePath = strAppBase + "/AutoRunLib.dll"; } else { strFilePath = strAppBase + "AutoRunLib.dll"; } // 本機執行:將DLL放在執行檔編譯後的位置底下 var mainAssembly = System.Reflection.Assembly.LoadFrom(strFilePath); // 建立Type物件 var hashType = mainAssembly.GetType("AutoRunLib.clsAutoRunLibrary"); // 使用ConstructorInfo建立物件 Type[] argumentTypes = Type.EmptyTypes; var ctor = hashType.GetConstructor(argumentTypes); // 因AutoRunLib.clsAutoRunLibrary會叫用到iMESLicxManager.dll,所以AutoRunLib.dll和iMESLicxManager.dll要放在同一個路徑底下,且app.config要設連線字串 var newHash = ctor.Invoke(new object[] { }); // 使用MethodInfo.Invoke執行 var meth = hashType.GetMethod("ExecuteFunction"); // 執行設定的Job strReturnMsg = Conversions.ToString(meth.Invoke(newHash, new object[] { strJobName, colParameters })); // 若對應的程式回傳為success, 則本程序也回傳Success // If strReturnMsg = "success" Then strStatus = "Success" if (Strings.Mid(strReturnMsg, 1, 7).ToLower() == "success") { strStatus = "Success"; // 2012/08/20,Even,需判斷若回傳值 =Success (第一字碼大寫時,造成 strStatus無判斷),因此故意不回傳值 strReturnMsg = ""; // 成功不顯示msg } else if (Strings.Mid(strReturnMsg, 1, 5) == "fail;") // 2013/01/14,Hank,狀態已是fail,故Msg不show { // 取ErrorCode string[] tmp = Strings.Split(strReturnMsg, ";"); if (tmp.Length >= 3) { if (tmp[1].Length == 11) { errorCode = tmp[1]; } } strReturnMsg = Strings.Replace(strReturnMsg, "fail;", "", 1, 1, CompareMethod.Text); // 拿掉前面的fail; } funWriteTxtFile("JobNo : " + strJobNo + ", Complete. " + strReturnMsg); } catch (Exception E2) { strMemo = "funProcessJob Error : " + E2.Message; funWriteTxtFile(strMemo); funWriteToAnEventLog(strMemo, EventLogEntryType.Error, 9000); } finally { try { // Job完成後的後續動作: // 刪除已經執行完畢之工作 (最先做, 減少執行完畢而未刪的情形) // 註記最後執行時間 // 增加log if (strStatus == "Success") { funEndProcessJob(strJobNo, strStatus, CInput(strReturnMsg), CInput(System.Windows.Forms.SystemInformation.ComputerName), StartTime, DateTime.Now, Convert.ToInt32(DateAndTime.DateDiff(DateInterval.Second, StartTime, DateTime.Now)), strMemo); } else { funEndProcessJob_ErrorCode(strJobNo, strStatus, CInput(strReturnMsg), CInput(System.Windows.Forms.SystemInformation.ComputerName), StartTime, DateTime.Now, Convert.ToInt32(DateAndTime.DateDiff(DateInterval.Second, StartTime, DateTime.Now)), strMemo, errorCode, "AutoRun"); } } catch (Exception E1) { strMemo = "funProcessJob (JobNo : " + strJobNo + ") Error : " + E1.Message; funWriteTxtFile(strMemo); funWriteToAnEventLog(strMemo, EventLogEntryType.Error, 9000); } finally { modAutoRun.gIntCurrentJobCount = modAutoRun.gIntCurrentJobCount - 1; } // 2017/12/26 OwenLiu, mantis:0043439, AutoRunService 問題調整 // 2014/06/25 YF, Job End if (CollectionJob.Contains(strJobNo)) { CollectionJob.Remove(strJobNo); } } } /// /// 執行Job完成後的後續動作 /// private int funEndProcessJob(string JobNo, string Status = defString, string ReturnMsg = defString, string ServerName = defString, DateTime StartTime = default(DateTime), DateTime EndTime = default(DateTime), int RunTime = defInteger, string Memo = defString) { int funEndProcessJobRet = default(int); // 刪除已經執行完畢之工作 (最先做, 減少執行完畢而未刪的情形) // 註記最後執行時間 // 增加log funEndProcessJobRet = -1; // //Web Service相關變數 var XmlDoc = new XmlDocument(); string InXml, OutXml, strIdentity, strParameter; try { // 將傳入參數組成XML字串 // 定義Identity string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); // 定義Parameter strParameter = string.Empty; string argvalue_name = "jobno"; string argname = "JobNo"; string argtype = "String"; string argdesc = ""; strParameter = CombineXMLParameter(argvalue_name, argname, argtype, JobNo, argdesc); if ((Status ?? "") != defString) { string argvalue_name1 = "status"; string argname1 = "Status"; string argtype1 = "String"; string argdesc1 = ""; strParameter += CombineXMLParameter(argvalue_name1, argname1, argtype1, Status, argdesc1); } if ((ReturnMsg ?? "") != defString) { string argvalue_name2 = "returnmsg"; string argname2 = "ReturnMsg"; string argtype2 = "String"; string argdesc2 = ""; strParameter += CombineXMLParameter(argvalue_name2, argname2, argtype2, ReturnMsg, argdesc2); } if ((ServerName ?? "") != defString) { string argvalue_name3 = "servername"; string argname3 = "ServerName"; string argtype3 = "String"; string argdesc3 = ""; strParameter += CombineXMLParameter(argvalue_name3, argname3, argtype3, ServerName, argdesc3); } if (StartTime != defDateTime) { string argvalue_name4 = "starttime"; string argname4 = "StartTime"; string argtype4 = "DateTime"; string argvalue = Strings.Format(StartTime, "yyyy/MM/dd HH:mm:ss"); string argdesc4 = ""; strParameter += CombineXMLParameter(argvalue_name4, argname4, argtype4, argvalue, argdesc4); } // 2016-11-09, Joe, Format日期格式 if (EndTime != defDateTime) { string argvalue_name5 = "endtime"; string argname5 = "EndTime"; string argtype5 = "DateTime"; string argvalue1 = Strings.Format(EndTime, "yyyy/MM/dd HH:mm:ss"); string argdesc5 = ""; strParameter += CombineXMLParameter(argvalue_name5, argname5, argtype5, argvalue1, argdesc5); } // 2016-11-09, Joe, Format日期格式 if (RunTime != defInteger) { string argvalue_name6 = "runtime"; string argname6 = "RunTime"; string argtype6 = "Integer"; string argvalue2 = RunTime.ToString(); string argdesc6 = ""; strParameter += CombineXMLParameter(argvalue_name6, argname6, argtype6, argvalue2, argdesc6); RunTime = Conversions.ToInteger(argvalue2); } if ((Memo ?? "") != defString) { string argvalue_name7 = "memo"; string argname7 = "Memo"; string argtype7 = "String"; string argdesc7 = ""; strParameter += CombineXMLParameter(argvalue_name7, argname7, argtype7, Memo, argdesc7); } // request XML字串 InXml = CombineXMLRequest(strIdentity, strParameter); OutXml = modAutoRun.InvokeSrv("wsAUT.funEndProcessJob", InXml); XmlDoc.LoadXml(OutXml); if (!chkExecutionSuccess(XmlDoc)) { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } funEndProcessJobRet = 0; } catch (Exception e1) { funWriteTxtFile("funEndProcessJob (JobNo : " + JobNo + ") Error : " + e1.Message); funWriteToAnEventLog("funEndProcessJob (JobNo : " + JobNo + ") Error : " + e1.Message, EventLogEntryType.Error, 9000); } return funEndProcessJobRet; } /// /// 執行Job完成後的後續動作 /// private int funEndProcessJob_ErrorCode(string JobNo, string Status = defString, string ReturnMsg = defString, string ServerName = defString, DateTime StartTime = default(DateTime), DateTime EndTime = default(DateTime), int RunTime = defInteger, string Memo = defString, string ErrorCode = "0000-999999", string LogClass = defString) { int funEndProcessJob_ErrorCodeRet = default(int); // 刪除已經執行完畢之工作 (最先做, 減少執行完畢而未刪的情形) // 註記最後執行時間 // 增加log funEndProcessJob_ErrorCodeRet = -1; // //Web Service相關變數 var XmlDoc = new XmlDocument(); string InXml, OutXml, strIdentity, strParameter; try { // 將傳入參數組成XML字串 // 定義Identity string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); // 定義Parameter strParameter = string.Empty; string argvalue_name = "jobno"; string argname = "JobNo"; string argtype = "String"; string argdesc = ""; strParameter = CombineXMLParameter(argvalue_name, argname, argtype, JobNo, argdesc); if ((Status ?? "") != defString) { string argvalue_name1 = "status"; string argname1 = "Status"; string argtype1 = "String"; string argdesc1 = ""; strParameter += CombineXMLParameter(argvalue_name1, argname1, argtype1, Status, argdesc1); } if ((ReturnMsg ?? "") != defString) { string argvalue_name2 = "returnmsg"; string argname2 = "ReturnMsg"; string argtype2 = "String"; string argdesc2 = ""; strParameter += CombineXMLParameter(argvalue_name2, argname2, argtype2, ReturnMsg, argdesc2); } if ((ServerName ?? "") != defString) { string argvalue_name3 = "servername"; string argname3 = "ServerName"; string argtype3 = "String"; string argdesc3 = ""; strParameter += CombineXMLParameter(argvalue_name3, argname3, argtype3, ServerName, argdesc3); } if (StartTime != defDateTime) { string argvalue_name4 = "starttime"; string argname4 = "StartTime"; string argtype4 = "DateTime"; string argvalue = Strings.Format(StartTime, "yyyy/MM/dd HH:mm:ss"); string argdesc4 = ""; strParameter += CombineXMLParameter(argvalue_name4, argname4, argtype4, argvalue, argdesc4); } // 2016-11-09, Joe, Format日期格式 if (EndTime != defDateTime) { string argvalue_name5 = "endtime"; string argname5 = "EndTime"; string argtype5 = "DateTime"; string argvalue1 = Strings.Format(EndTime, "yyyy/MM/dd HH:mm:ss"); string argdesc5 = ""; strParameter += CombineXMLParameter(argvalue_name5, argname5, argtype5, argvalue1, argdesc5); } // 2016-11-09, Joe, Format日期格式 if (RunTime != defInteger) { string argvalue_name6 = "runtime"; string argname6 = "RunTime"; string argtype6 = "Integer"; string argvalue2 = RunTime.ToString(); string argdesc6 = ""; strParameter += CombineXMLParameter(argvalue_name6, argname6, argtype6, argvalue2, argdesc6); RunTime = Conversions.ToInteger(argvalue2); } if ((Memo ?? "") != defString) { string argvalue_name7 = "memo"; string argname7 = "Memo"; string argtype7 = "String"; string argdesc7 = ""; strParameter += CombineXMLParameter(argvalue_name7, argname7, argtype7, Memo, argdesc7); } if ((LogClass ?? "") != defString) { string argvalue_name8 = "logclass"; string argname8 = "LogClass"; string argtype8 = "String"; string argdesc8 = ""; strParameter += CombineXMLParameter(argvalue_name8, argname8, argtype8, LogClass, argdesc8); } string argvalue_name9 = "errorcode"; string argname9 = "ErrorCode"; string argtype9 = "String"; string argdesc9 = ""; strParameter += CombineXMLParameter(argvalue_name9, argname9, argtype9, ErrorCode, argdesc9); // request XML字串 InXml = CombineXMLRequest(strIdentity, strParameter); OutXml = modAutoRun.InvokeSrv("wsAUT.funEndProcessJob_ErrorCode", InXml); XmlDoc.LoadXml(OutXml); if (!chkExecutionSuccess(XmlDoc)) { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } funEndProcessJob_ErrorCodeRet = 0; } catch (Exception e1) { funWriteTxtFile("funEndProcessJob (JobNo : " + JobNo + ") Error : " + e1.Message); funWriteToAnEventLog("funEndProcessJob (JobNo : " + JobNo + ") Error : " + e1.Message, EventLogEntryType.Error, 9000); } return funEndProcessJob_ErrorCodeRet; } /// /// 啟動時先刪除資料庫中上次執行的殘留JobQueue /// /// public void funDelMesAutoRunQueue() { // //Web Service相關變數 var XmlDoc = new XmlDocument(); string InXml, OutXml, strIdentity, strParameter; // 組InXml的字串 string argSendTime = Conversions.ToString(DateTime.Now); strIdentity = CombineXMLIdentity(modWIN.gComputerName, modWIN.gUserNo, argSendTime); string argvalue_name = "servername"; string argname = "ServerName"; string argtype = "String"; string argdesc = ""; strParameter = CombineXMLParameter(argvalue_name, argname, argtype, System.Windows.Forms.SystemInformation.ComputerName.ToString().ToUpper(), argdesc); InXml = CombineXMLRequest(strIdentity, strParameter); try { // OutXml = wsAUT.DelMesAutoRunQueue(InXml) OutXml = modAutoRun.InvokeSrv("wsAUT.DelMesAutoRunQueue", InXml); // 利用XmlDoc物件處理ReturnValue XmlDoc.LoadXml(OutXml); if (!chkExecutionSuccess(XmlDoc)) { throw new Exception(GetExceptionSysMsg(XmlDoc) + '\r' + GetExceptionMesMsg(XmlDoc)); } } catch (Exception e1) { funWriteTxtFile("funDelMesAutoRunQueue Error : " + e1.Message); funWriteToAnEventLog("funDelMesAutoRunQueue Error : " + e1.Message, EventLogEntryType.Error, 9000); } } private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs args) { try { Exception e = (Exception)args.ExceptionObject; funWriteTxtFile(e.Message); funWriteToAnEventLog(e.Message, EventLogEntryType.Error, 9000); } catch (Exception ex) { } } // 2017/12/26 OwenLiu, mantis:0043439, AutoRunService 問題調整 // 2014/06/25 YF, 將tblJobQueue內Running的Job與CollectionJob做比對, 來判斷Job是否已死在Queue內 // 若CollectionJob沒有此JobNo, 則表示Job已死, 將Job狀態改為Standby, 即可再繼續執行 private void CheckJobIsDead() { try { foreach (DataRow row in modAutoRun.dsJobQueue.Tables[tblJobQueue].Select("(ServerName is null Or ServerName='' Or ServerName='" + System.Windows.Forms.SystemInformation.ComputerName.ToString().ToUpper() + "') and STATUS='Running'")) { if (!CollectionJob.Contains(Conversions.ToString(row["JobNo"]))) { row["Status"] = "Standby"; } } } catch (Exception ex) { funWriteTxtFile("CheckJobIsDead Error: " + ex.Message); funWriteToAnEventLog(ex.Message, EventLogEntryType.Error, 9000); } } } }