using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using static System.Configuration.ConfigurationManager; using System.Data; using System.Diagnostics; using System.IO; using System.Runtime.CompilerServices; using System.Xml; using Microsoft.VisualBasic; using Microsoft.VisualBasic.CompilerServices; using static iMESCore.DataBase.iMESSql; namespace IEWService { public partial class IEWService { #region 列舉型別 public enum ExecuteResultEnum : int { SUCCESS = 0, // 成功 FAIL = 1 // 失敗 } // 警示DB類型 public enum AlertDBTypeEnum : int { RealTime = 0, // 即時資料庫 History = 1 // 歷史資料庫 } // 警示類型 // 2014/01/17 YF, 加入PRD & OP public enum AlertTypeEnum : int { ERF = 1, // ERFNo LOT = 2, // LotNo EQP = 3, // EQPNo ACC = 4, // AccNo MO = 5, // MONo PRD = 6, // PRD OP = 7 // OP } // 資料型態 public enum DataTypeEnum : int { NumericType = 0, // 數值型態 StringType = 1, // 字串型態 DateTimeType = 3 // 日期型態 } // 條件週期 public enum DataPeriodEnum : int { Minute = 0, // 分鐘 Hour = 1, // 小時 Day = 2, // 天 Month = 3 // 月 } // 警示事件類型 public enum AlertEventTypeEnum : int { DEF = 0, // 預設事件 CUS = 1 // 自定義事件 } #endregion private const int CHECKEVENT_INTERVAL = 300; // 每隔300秒鐘, 檢查是否有符合週期的預警事件 private int MAX_RUNNINGJOB_COUNT = 5; // 允許同時執行預警事件數量 private BackgroundWorker[] workers; // 用來執行預警事件的執行緒 private BackgroundWorker WorkerMain; // 主執行緒, 用來啟動Event, EventLog, AutoRunLog and Delivery執行緒 private BackgroundWorker WorkerEvent; // 預警事件執行緒, 指派QueueEvent的預警事件給workers private BackgroundWorker WorkerEventLog; // 預警事件Log執行緒, 將QueueEventLog的資料寫入資料庫 private BackgroundWorker WorkerAutoRunLog; // AutoRunLog執行緒, 將QueueAutoRunLog的資料寫入資料庫 private BackgroundWorker WorkerDelivery; // 派送執行緒, 派送QueueDelivery的資料 private IEWQueue _QueueEvent; private IEWQueue QueueEvent { [MethodImpl(MethodImplOptions.Synchronized)] get { return _QueueEvent; } [MethodImpl(MethodImplOptions.Synchronized)] set { if (_QueueEvent != null) { _QueueEvent.AddComplete -= QueueEvent_AddComplete; } _QueueEvent = value; if (_QueueEvent != null) { _QueueEvent.AddComplete += QueueEvent_AddComplete; } } } private IEWQueue _QueueEventLog; private IEWQueue QueueEventLog { [MethodImpl(MethodImplOptions.Synchronized)] get { return _QueueEventLog; } [MethodImpl(MethodImplOptions.Synchronized)] set { if (_QueueEventLog != null) { _QueueEventLog.AddComplete -= QueueEventLog_AddComplete; } _QueueEventLog = value; if (_QueueEventLog != null) { _QueueEventLog.AddComplete += QueueEventLog_AddComplete; } } } private IEWQueue _QueueAutoRunLog; private IEWQueue QueueAutoRunLog { [MethodImpl(MethodImplOptions.Synchronized)] get { return _QueueAutoRunLog; } [MethodImpl(MethodImplOptions.Synchronized)] set { if (_QueueAutoRunLog != null) { _QueueAutoRunLog.AddComplete -= QueueAutoRunLog_AddComplete; } _QueueAutoRunLog = value; if (_QueueAutoRunLog != null) { _QueueAutoRunLog.AddComplete += QueueAutoRunLog_AddComplete; } } } private IEWQueue _QueueDelivery; private IEWQueue QueueDelivery { [MethodImpl(MethodImplOptions.Synchronized)] get { return _QueueDelivery; } [MethodImpl(MethodImplOptions.Synchronized)] set { if (_QueueDelivery != null) { _QueueDelivery.AddComplete -= QueueDelivery_AddComplete; } _QueueDelivery = value; if (_QueueDelivery != null) { _QueueDelivery.AddComplete += QueueDelivery_AddComplete; } } } // 即時&歷史資料庫連線相關資料 private DatabaseInfo dbi = new DatabaseInfo(); private iMESLog.MESLog logger; public IEWService() { QueueEvent = new IEWQueue(); // 預警事件Queue, 符合執行週期的事件會放入此Queue QueueEventLog = new IEWQueue(); // 預警事件Log Queue, 預警事件執行後, 將觸發結果放入此Queue QueueAutoRunLog = new IEWQueue(); // AutoRunLog Queue, 預警事件執行後, 將要Log的資料放入此Queue QueueDelivery = new IEWQueue(); // 派送Queue, 預警事件觸發後, 將要派送的資料放入此Queue InitializeComponent(); } protected override void OnStart(string[] args) { try { // 取出允許同時執行預警事件數量 MAX_RUNNINGJOB_COUNT = Convert.ToInt32(AppSettings["MaxRunningJobCount"]); logger = new iMESLog.MESLog(GetType().ToString()); } catch (Exception ex) { } workers = new BackgroundWorker[MAX_RUNNINGJOB_COUNT]; // 建立主執行緒 WorkerMain = new BackgroundWorker(); WorkerMain.DoWork += Main_DoWork; WorkerMain.RunWorkerCompleted += Main_RunWorkerCompleted; WorkerMain.RunWorkerAsync(); // 設定檢查是否有符合週期的預警事件的間隔秒數 TimerCheckEvent.Interval = CHECKEVENT_INTERVAL * 1000; TimerCheckEvent.Enabled = true; funWriteTxtFile("Service Started."); } protected override void OnStop() { TimerCheckEvent.Enabled = false; var result = new AutoRunLog(); try { result.AlertEventID = "IEW Service Stop"; result.AlertEventName = result.AlertEventID; result.StartTime = DateTime.Now; workers = null; WorkerMain = null; WorkerEvent = null; WorkerEventLog = null; WorkerAutoRunLog = null; WorkerDelivery = null; QueueEvent = null; QueueEventLog = null; QueueAutoRunLog = null; QueueDelivery = null; dbi = null; result.ExecuteResult = ExecuteResultEnum.SUCCESS; result.ErrorMessage = "Success"; funWriteTxtFile("Service Stopped."); } catch (Exception ex) { result.ExecuteResult = ExecuteResultEnum.FAIL; result.ErrorMessage = ex.Message; funWriteTxtFile("Service Error : " + ex.Message + ".", ex); } finally { result.EndTime = DateTime.Now; WriteToAnEventLog(result, EventLogEntryType.Information, 9000); result = null; } } private void TimerCheckEvent_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { try { TimerCheckEvent.Enabled = false; funWriteTxtFile("CheckEvent"); CheckEvent(); } catch (Exception ex) { } finally { TimerCheckEvent.Enabled = true; } } #region CheckEvent /// /// 取出符合執行週期的預警事件 /// /// private void CheckEvent() { var result = new AutoRunLog(); string strSQL; DataTable dtTemp = null; string str10MinIntervalSQLString; string strSpecificSQLString; int intCheckTimePoint = 6; int intCheckTimeOver = 60 - intCheckTimePoint; try { result.LogID = "N/A"; result.AlertEventID = "CheckEvent"; result.AlertEventName = result.AlertEventID; result.StartTime = DateTime.Now; // 將失效事件的狀態改為非作用中 strSQL = " Update TBLIEWALERTEVENTBASIS " + " Set Status = 1 "; if (dbi.RealDB.DatabaseType.ToLower() != "oracle") { strSQL += " Where INVALIDDATE < GETDATE() "; } else { strSQL += " Where INVALIDDATE < Sysdate "; } //var cn = CreateConnection(dbi.RealDB.ConnectionString); //using (var cmd = CreateCommand(strSQL, cn)) //{ // string cmdTmp = cmd.ToString(); // //cn.Open(); // cmd.ExecuteNonQuery(); // cn.Close(); //} ExecuteSQLNoneQuery(dbi.RealDB.DatabaseType, dbi.RealDB.ConnectionString, ref strSQL); // 取出符合執行週期的預警事件 if (dbi.RealDB.DatabaseType.ToLower() != "oracle") { // SQL Server // 20190213 FixBy KevinChang 0054942: 6.0.3.5 智慧預警派送頻率問題 // str10MinIntervalSQLString = "(RUNFREQUENT = 'Each10Min' and (LASTRUNTIME is null or LASTRUNTIME <= Cast('" & Format(Now.AddMinutes(-10).AddSeconds(intCheckTimePoint * 60), "yyyy/MM/dd HH:mm:ss") & "' as datetime)))" str10MinIntervalSQLString = "(RUNFREQUENT = 'Each10Min' and (LASTRUNTIME is null or LASTRUNTIME <= Cast('" + Strings.Format(DateTime.Now.AddMinutes(-10), "yyyy/MM/dd HH:mm:ss") + "' as datetime)))"; } else { // Oracle // 20190213 FixBy KevinChang 0054942: 6.0.3.5 智慧預警派送頻率問題 // str10MinIntervalSQLString = "(RUNFREQUENT = 'Each10Min' and (LASTRUNTIME is null or LASTRUNTIME <= TO_DATE('" & Format(Now.AddMinutes(-10).AddSeconds(intCheckTimePoint * 60), "yyyy/MM/dd HH:mm:ss") & "','YYYY/MM/DD HH24:MI:SS')))" str10MinIntervalSQLString = "(RUNFREQUENT = 'Each10Min' and (LASTRUNTIME is null or LASTRUNTIME <= TO_DATE('" + Strings.Format(DateTime.Now.AddMinutes(-10), "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')))"; } // 取出指定時間要執行的job if (dbi.RealDB.DatabaseType.ToLower() != "oracle") { // SQL Server strSpecificSQLString = "( LASTRUNTIME < CAST('" + Strings.Format(DateTime.Now.AddSeconds(-intCheckTimePoint * 60), "yyyy/MM/dd HH:mm:ss") + "' as datetime))"; } else { // Oracle strSpecificSQLString = "( LASTRUNTIME < TO_DATE('" + Strings.Format(DateTime.Now.AddSeconds(-intCheckTimePoint * 60), "yyyy/MM/dd HH:mm:ss") + "','YYYY/MM/DD HH24:MI:SS'))"; } strSpecificSQLString += " and ((RUNYEAR is null or RUNYEAR = '" + Strings.Format(DateTime.Now.Year, "0000") + "')"; strSpecificSQLString += " and ( RUNMONTH is null or RUNMONTH = '" + Strings.Format(DateTime.Now.Month, "00") + "')"; strSpecificSQLString += " and ( RUNDAY is null or RUNDAY = '" + Strings.Format(DateTime.Now.Day, "00") + "')"; strSpecificSQLString += " and ( RUNWEEK is null or RUNWEEK = '" + DateTime.Now.DayOfWeek.ToString() + "')"; strSpecificSQLString += " and ( RUNHOUR is null or RUNHOUR = '" + Strings.Format(DateTime.Now, "HH") + "')"; // 取出指定時間要執行的job之2 // 若n分鐘內, 包含跨小時, 跨日, 跨月, 跨年,則 if (DateTime.Now.Minute > intCheckTimeOver) { strSpecificSQLString += " and ( RUNMIN>='" + Strings.Format(DateTime.Now.Minute, "00") + "' AND RUNMIN<'60'))"; strSpecificSQLString += " or (( RUNYEAR is null or RUNYEAR='" + Strings.Format(DateTime.Now.AddMinutes(intCheckTimePoint).Year, "0000") + "' or RUNYEAR = '')"; strSpecificSQLString += " and ( RUNMONTH is null or RUNMONTH='" + Strings.Format(DateTime.Now.AddMinutes(intCheckTimePoint).Month, "00") + "' or RUNMONTH ='')"; strSpecificSQLString += " and ( RUNDAY is null or RUNDAY='" + Strings.Format(DateTime.Now.AddMinutes(intCheckTimePoint).Day, "00") + "' or RUNDAY = '')"; strSpecificSQLString += " and ( RUNWEEK is null or RUNWEEK='" + DateTime.Now.AddMinutes(intCheckTimePoint).DayOfWeek.ToString() + "' or RUNWEEK = '')"; strSpecificSQLString += " and ( RUNHOUR is null or RUNHOUR='" + Strings.Format(DateTime.Now.AddMinutes(intCheckTimePoint), "HH") + "')"; strSpecificSQLString += " and ( RUNMIN>='00' AND RUNMIN<'" + Strings.Format(DateTime.Now.AddMinutes(intCheckTimePoint).Minute, "00") + "'))"; } else { strSpecificSQLString += " and ( RUNMIN>='" + Strings.Format(DateTime.Now.Minute, "00") + "' AND RUNMIN<'" + Strings.Format(DateTime.Now.AddMinutes(intCheckTimePoint).Minute, "00") + "'))"; } strSQL = " Select * " + " From tblIEWAlertEventBasis " + " Where Status = 0 " + " And ( (LASTRUNTIME is null) or (" + strSpecificSQLString + ") or (" + str10MinIntervalSQLString + "))"; //using (var da = new System.Data.OleDb.OleDbDataAdapter(strSQL, dbi.RealDB.ConnectionString)) //{ // dtTemp = new DataTable(); // da.Fill(dtTemp); //} ExecuteSQLQuery_Adapter(strSQL, dtTemp, dbi.RealDB.ConnectionString, dbi.RealDB.DatabaseType); // 將要執行且不存在Quene的預警事件放入Queue foreach (DataRow row in dtTemp.Rows) { var ae = new AlertEvent(row); if (!QueueEvent.Contains(ae)) { ae.LogID = Guid.NewGuid().ToString(); QueueEvent.Add(ae); funWriteTxtFile(string.Format("Add Event To Queue.{2}{0}:{1}:", ae.AlertEventID, ae.AlertEventName, Constants.vbCrLf)); } } result.EndTime = DateTime.Now; result.ExecuteResult = ExecuteResultEnum.SUCCESS; result.ErrorMessage = "Success"; } catch (Exception ex) { result.EndTime = DateTime.Now; result.ExecuteResult = ExecuteResultEnum.FAIL; result.ErrorMessage = ex.Message; QueueAutoRunLog.Add(result); } finally { if (dtTemp != null) { dtTemp.Dispose(); dtTemp = null; } result = null; } } #endregion #region 主執行緒 /// /// 主執行緒非同步作業開始, 用來啟動其它執行緒 /// /// /// /// private void Main_DoWork(object sender, DoWorkEventArgs e) { var result = new AutoRunLog(); try { result.AlertEventID = "IEW Service Start"; funWriteTxtFile("IEW Service Start"); result.AlertEventName = result.AlertEventID; result.StartTime = DateTime.Now; // 建立執行預警事件的執行緒 for (int i = 0, loopTo = MAX_RUNNINGJOB_COUNT - 1; i <= loopTo; i++) { workers[i] = new BackgroundWorker(); workers[i].DoWork += DoWork; workers[i].RunWorkerCompleted += RunWorkerCompleted; } // 啟動預警事件QUEUE的執行緒 WorkerEvent = new BackgroundWorker(); WorkerEvent.DoWork += Event_DoWork; WorkerEvent.RunWorkerCompleted += Event_RunWorkerCompleted; // 啟動預警事件Log QUEUE的執行緒 WorkerEventLog = new BackgroundWorker(); WorkerEventLog.DoWork += EventLog_DoWork; WorkerEventLog.RunWorkerCompleted += EventLog_RunWorkerCompleted; // 啟動AutoRunLog QUEUE的執行緒 WorkerAutoRunLog = new BackgroundWorker(); WorkerAutoRunLog.DoWork += AutoRunLog_DoWork; WorkerAutoRunLog.RunWorkerCompleted += AutoRunLog_RunWorkerCompleted; // 啟動派送QUEUE的執行緒 WorkerDelivery = new BackgroundWorker(); WorkerDelivery.DoWork += Delivery_DoWork; WorkerDelivery.RunWorkerCompleted += Delivery_RunWorkerCompleted; result.ExecuteResult = ExecuteResultEnum.SUCCESS; result.ErrorMessage = "Success"; funWriteTxtFile("Success"); } catch (Exception ex) { result.ExecuteResult = ExecuteResultEnum.FAIL; result.ErrorMessage = ex.Message; funWriteTxtFile(ex.Message, ex); } finally { result.EndTime = DateTime.Now; e.Result = result; } } /// /// 主執行緒非同步作業結束 /// /// /// /// private void Main_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { AutoRunLog result = (AutoRunLog)e.Result; // 寫入Windows事件檢視器, 可由事件檢視器查看是否啟動成功 if (result.ExecuteResult == ExecuteResultEnum.SUCCESS) { WriteToAnEventLog(result, EventLogEntryType.Information, 9000); } else { WriteToAnEventLog(result, EventLogEntryType.Error, 9000); } } #endregion #region 預警事件Queue執行緒 /// /// 預警事件Queue非同步作業開始 /// /// /// /// private void Event_DoWork(object sender, DoWorkEventArgs e) { AlertEvent ae = null; AutoRunLog result = null; AutoRunLog result2 = null; try { result2 = new AutoRunLog(); result2.LogID = "N/A"; result2.AlertEventID = "Event_DoWork"; result2.AlertEventName = result2.AlertEventID; result2.StartTime = DateTime.Now; // 逐筆處理Queue內的預警事件 while (QueueEvent.Count > 0) { try { // 取出Queue中的第一筆預警事件 ae = QueueEvent[0]; result = new AutoRunLog(ae); // 找出空閒的執行緒 for (int i = 0, loopTo = MAX_RUNNINGJOB_COUNT - 1; i <= loopTo; i++) { if (workers[i].IsBusy) { continue; } else { // 指派AlertEvent給執行緒, 並開始執行 workers[i].RunWorkerAsync(ae); // 指派事件成功 result.ExecuteResult = ExecuteResultEnum.SUCCESS; result.ErrorMessage = "指派事件成功"; break; } } } catch (Exception ex) { // 指派事件失敗 result.ExecuteResult = ExecuteResultEnum.FAIL; result.ErrorMessage = "指派事件失敗, " + ex.Message; } finally { if (result.ExecuteResult == ExecuteResultEnum.SUCCESS || result.ExecuteResult == ExecuteResultEnum.FAIL) { result.EndTime = DateTime.Now; QueueEvent.Remove(ae); QueueAutoRunLog.Add(result); } } } result2 = null; } catch (Exception ex) { result2.EndTime = DateTime.Now; result2.ExecuteResult = ExecuteResultEnum.FAIL; result2.ErrorMessage = ex.Message; funWriteTxtFile(ex.Message, ex); } finally { e.Result = result2; } } /// /// 預警事件Queue非同步作業結束 /// /// /// /// private void Event_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { AutoRunLog result = (AutoRunLog)e.Result; if (result != null && result.ExecuteResult == ExecuteResultEnum.FAIL) { QueueAutoRunLog.Add(result); } } #endregion #region 預警事件執行緒 /// /// 執行預警事件非同步執行作業開始 /// /// /// /// private void DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; AlertEvent ae = (AlertEvent)e.Argument; DataTable dtTemp = null; DataTable dtResult = null; string strSQL = ""; string strConnString = ""; AutoRunLog result = null; try { funWriteTxtFile(string.Format("Process Queue.{2}{0}:{1}", ae.AlertEventID, ae.AlertEventName, Constants.vbCrLf)); result = new AutoRunLog(ae); // 取出預警事件語法及條件 if (ae.AlertEventType == AlertEventTypeEnum.CUS) { // 自定義事件 strSQL = " Select A.AlertEventID, A.AlertEventName, A.Subject, A.Recipient, A.Description, A.Creator, B.ItemNo, " + " B.CondField, B.CondDataType, B.CondOperator, B.CondValue, B.CondPeriod, B.CondPeriodTime, " + " C.AlertDBType, C.AlertType, C.AlertScript, B.InsertName " + " From tblIEWAlertEventBasis A " + " Left Join tblIEWAlertCondition B " + " On A.AlertEventID = B.AlertEventID " + " Inner Join tblIEWAlertBasis C " + " On A.AlertEventSource = C.AlertNo " + " Where A.AlertEventID = '" + ae.AlertEventID + "'"; } // 預設事件 // Oracle & MSSQL Script使用不同欄位 else if (dbi.RealDB.DatabaseType.ToLower() == "oracle") { strSQL = " Select A.AlertEventID, A.AlertEventName, A.Subject, A.Recipient, A.Description, A.Creator, B.ItemNo, " + " B.CondField, B.CondDataType, B.CondOperator, B.CondValue, B.CondPeriod, B.CondPeriodTime, " + " C.AlertDBType, C.AlertType, C.EventScript As AlertScript, B.InsertName " + " From tblIEWAlertEventBasis A " + " Left Join tblIEWAlertCondition B " + " On A.AlertEventID = B.AlertEventID " + " Inner Join tblIEWDefaultEventBasis C " + " On A.AlertEventSource = C.DefEventID " + " Where A.AlertEventID = '" + ae.AlertEventID + "'"; } else { strSQL = " Select A.AlertEventID, A.AlertEventName, A.Subject, A.Recipient, A.Description, A.Creator, B.ItemNo, " + " B.CondField, B.CondDataType, B.CondOperator, B.CondValue, B.CondPeriod, B.CondPeriodTime, " + " C.AlertDBType, C.AlertType, C.EventScript_MSSQL As AlertScript, B.InsertName " + " From tblIEWAlertEventBasis A " + " Left Join tblIEWAlertCondition B " + " On A.AlertEventID = B.AlertEventID " + " Inner Join tblIEWDefaultEventBasis C " + " On A.AlertEventSource = C.DefEventID " + " Where A.AlertEventID = '" + ae.AlertEventID + "'"; } //using (var da = new System.Data.OleDb.OleDbDataAdapter(strSQL, dbi.RealDB.ConnectionString)) //{ // // 2022/11/2,Ning,121417: 台基:服务日志报错:未将对象引用设置到对象的实例 // // da.SelectCommand.Parameters.AddWithValue("AlertEventID", ae.AlertEventID) // dtTemp = new DataTable(); // da.Fill(dtTemp); //} //IDbConnection cn = CreateConnection(); ExecuteSQLQuery_Adapter(strSQL, dtTemp, dbi.RealDB.ConnectionString, dbi.RealDB.DatabaseType); if (dtTemp.Rows.Count == 0) { throw new Exception("AlertEventID(" + ae.AlertEventID + ")" + Constants.vbCrLf + "警示事件主檔取出失敗!"); } if (string.IsNullOrEmpty(dtTemp.Rows[0]["AlertScript"].ToString())) { throw new Exception("AlertEventID(" + ae.AlertEventID + ")" + Constants.vbCrLf + "AlertEventType(" + dtTemp.Rows[0]["AlertEventType"].ToString() + ")" + Constants.vbCrLf + "AlertEventSource(" + dtTemp.Rows[0]["AlertEventSource"].ToString() + ")" + Constants.vbCrLf + "警示語法是空值!"); } string strDBType; if (Convert.ToInt32(dtTemp.Rows[0]["AlertDBType"]) == (int)AlertDBTypeEnum.RealTime) { strConnString = dbi.RealDB.ConnectionString; strDBType = dbi.RealDB.DatabaseType; } else { strConnString = dbi.HistoryDB.ConnectionString; strDBType = dbi.HistoryDB.DatabaseType; } // 警示類型 1:ERF, 2:LOT, 3:EQP, 4:ACC, 5:MO ae.AlertType = (AlertTypeEnum)Conversions.ToInteger(dtTemp.Rows[0]["AlertType"]); // 產生SQL語法 strSQL = GenerateSQLScript(dtTemp); //using (var da = new System.Data.OleDb.OleDbDataAdapter(strSQL, strConnString)) //{ // dtResult = new DataTable(); // da.Fill(dtResult); //} //IDbConnection CNstrConnString = CreateConnection(strConnString); ExecuteSQLQuery_Adapter(strSQL, dtResult, strConnString, strDBType); if (dtResult != null && dtResult.Rows.Count > 0) { ae.ResultTable = dtResult; // 寫入派送Queue QueueDelivery.Add(ae); // 寫入警示事件Log Queue QueueEventLog.Add(ae); funWriteTxtFile(string.Format("Add Queue To Delivery.{2}{0}:{1}", ae.AlertEventID, ae.AlertEventName, Constants.vbCrLf)); } result.ExecuteResult = ExecuteResultEnum.SUCCESS; result.ErrorMessage = "執行事件成功"; funWriteTxtFile("執行事件成功 執行事件名稱: " + ae.AlertEventName + ""); } catch (Exception ex) { result.ExecuteResult = ExecuteResultEnum.FAIL; result.ErrorMessage = "執行事件失敗, " + ex.Message; funWriteTxtFile("執行事件失敗 執行事件名稱: " + ae.AlertEventName + " " + ex.Message, ex); } finally { dtTemp = null; dtResult = null; e.Result = result; } } /// /// 預警事件非同步執行作業結束 /// /// /// /// private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; AutoRunLog result = (AutoRunLog)e.Result; if (result == null) { return; } result.EndTime = DateTime.Now; // 寫入AutoRunLog Queue QueueAutoRunLog.Add(result); // 寫回最後執行時間 WriteLastRunTime(result); } /// /// 產生SQL語法 /// /// /// /// private string GenerateSQLScript(DataTable pTable) { string strResult = ""; string strOperator; DataTypeEnum intDataType; string strSymbol; string strCondValue; // Dim strScript As String string strCondition = ""; string strCondition2 = ""; // Dim intGroupBy, intOrderBy As Integer // Dim strBody As String // Dim i As Integer var htScriptCond = new Hashtable(); // 逐筆產生Where條件 foreach (DataRow row in pTable.Rows) { // 運算子或週期需指定其一 if (string.IsNullOrEmpty(row["CondOperator"].ToString()) && row["CondPeriod"] is DBNull) { throw new Exception("AlertEventID(" + row["A.AlertEventID"].ToString() + "), ItemNo(" + row["ItemNo"].ToString() + ")需指定運算子或週期!"); } // 指定運算子, 條件值不可是空值 if (!string.IsNullOrEmpty(row["CondOperator"].ToString()) && string.IsNullOrEmpty(row["CondValue"].ToString())) { throw new Exception("AlertEventID(" + row["A.AlertEventID"].ToString() + "), ItemNo(" + row["ItemNo"].ToString() + ")條件值不可是空值!"); } // 指定週期, 週期時間不可是空值 if (string.IsNullOrEmpty(row["CondOperator"].ToString()) && row["CondPeriodTime"] is DBNull) { throw new Exception("AlertEventID(" + row["A.AlertEventID"].ToString() + "), ItemNo(" + row["ItemNo"].ToString() + ")週期時間不可是空值!"); } strCondition2 = ""; intDataType = (DataTypeEnum)Conversions.ToInteger(row["CondDataType"]); strOperator = row["CondOperator"].ToString().ToUpper(); strCondValue = row["CondValue"].ToString(); if (!string.IsNullOrEmpty(row["InsertName"].ToString()) && !htScriptCond.ContainsKey(row["InsertName"].ToString().ToUpper())) { htScriptCond.Add(row["InsertName"].ToString().ToUpper(), ""); } if (string.IsNullOrEmpty(strOperator)) { // 依週期 if (dbi.RealDB.DatabaseType.ToLower() == "oracle") { strCondition2 += " And (Sysdate - " + row["CondField"].ToString() + ") "; switch ((DataPeriodEnum)Conversions.ToInteger(row["CondPeriod"])) { case DataPeriodEnum.Minute: { strCondition2 += " * 24 * 60 "; break; } case DataPeriodEnum.Hour: { strCondition2 += " * 24 "; break; } case DataPeriodEnum.Day: { strCondition2 += ""; break; } case DataPeriodEnum.Month: { strCondition2 += " / 30 "; break; } default: { throw new Exception("無法識別條件週期CondPeriod(" + row["CondPeriod"].ToString() + ")!"); } } strCondition2 += " >= " + row["CondPeriodTime"].ToString(); } else { string interval = ""; switch ((DataPeriodEnum)Conversions.ToInteger(row["CondPeriod"])) { case DataPeriodEnum.Minute: { interval = DataPeriodEnum.Minute.ToString(); break; } case DataPeriodEnum.Hour: { interval = DataPeriodEnum.Hour.ToString(); break; } case DataPeriodEnum.Day: { interval = DataPeriodEnum.Day.ToString(); break; } case DataPeriodEnum.Month: { interval = DataPeriodEnum.Month.ToString(); break; } default: { throw new Exception("無法識別條件週期CondPeriod(" + row["CondPeriod"].ToString() + ")!"); } } strCondition2 += " And DateDiff(" + interval + ", " + row["CondField"].ToString() + ", GETDATE()) >= " + row["CondPeriodTime"].ToString(); } } else { // 依運算子 // 資料型態的符號 if (intDataType == DataTypeEnum.StringType) { strSymbol = "'"; } else { strSymbol = ""; } // 依運算子設定條件值 switch (strOperator ?? "") { case "IN": { strCondValue = strCondValue.ToString().Replace(",", strSymbol + "," + strSymbol); break; } case "LIKE": { strCondValue += "%"; break; } } strCondValue = strSymbol + strCondValue + strSymbol; strCondition2 += " And " + row["CondField"].ToString() + " " + strOperator + " "; // 2022/7/5, Ning, 運算子為IN時, 需加上前後的括號 if (strOperator == "IN") { strCondition2 = strCondition2 + "("; } if (intDataType == DataTypeEnum.DateTimeType) { if (dbi.RealDB.DatabaseType.ToLower() == "oracle") { strCondition2 += " To_Date('" + Strings.Format(Conversions.ToDate(strCondValue), "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')"; } else { strCondition2 += " '" + Strings.Format(Conversions.ToDate(strCondValue), "yyyy/MM/dd H:mm:ss") + "' "; } } else { strCondition2 += strCondValue; } // 2022/7/5, Ning, 運算子為IN時, 需加上前後的括號 if (strOperator == "IN") { strCondition2 = strCondition2 + ")"; } } if (string.IsNullOrEmpty(row["InsertName"].ToString())) { strCondition += strCondition2; } else { htScriptCond[row["InsertName"].ToString().ToUpper()] = htScriptCond[row["InsertName"].ToString().ToUpper()].ToString() + strCondition2; } } // 判斷Where // strScript = pTable.Rows(0)("AlertScript").ToString.ToLower // If (strCondition <> "") Then // If strScript.Contains("where") = True Then '有Where,需要判斷 // If strScript.Contains(")") = False Then '沒有括弧,where在最外層 // '不置換And成為Where // Else '有括弧,判斷where是否在最外層 // Dim blnHaveWhere As Boolean = False ' // Dim ScriptChar() As Char = strScript.ToCharArray // i = 0 // For j As Integer = 0 To ScriptChar.Length - 1 // If ScriptChar(j) = "(" Then '進入子查詢, 紀錄+1 // i += 1 // ElseIf ScriptChar(j) = ")" Then '離開子查詢, 紀錄-1 // i -= 1 // ElseIf ScriptChar(j) = "w" Then 'where的起始點 // If j + 4 <= ScriptChar.Length - 1 Then // If strScript.Substring(j, 5) = "where" AndAlso i <= 0 Then // blnHaveWhere = True // Exit For // End If // End If // Else '其他字元不處理 // End If // Next // If blnHaveWhere = False Then // strCondition = Replace(strCondition, "And", "Where", 1, 1, CompareMethod.Text) // End If // End If // Else '一個where都沒有,將開頭And換成Where // strCondition = Replace(strCondition, "And", "Where", 1, 1, CompareMethod.Text) // End If // End If // 將有指定位置的條件插入 foreach (DictionaryEntry de in htScriptCond) pTable.Rows[0]["AlertScript"] = pTable.Rows[0]["AlertScript"].ToString().Replace("/*" + de.Key.ToString() + "*/", de.Value.ToString()); // ' 處理Group By及Order By // If (strScript.LastIndexOf("group by") <> -1) Then ' 有group by,需要判斷 // If (strScript.Contains(")")) = False Then ' 沒有括弧,group by在最外層 // intGroupBy = strScript.LastIndexOf("group by") // Else ' 有括弧,判斷group by是否在最外層 // Dim blnHaveGroupBy As Boolean = False // Dim ScriptChar() As Char = strScript.ToCharArray // i = 0 // For j As Integer = 0 To ScriptChar.Length - 1 // If ScriptChar(j) = "(" Then '進入子查詢, 紀錄+1 // i += 1 // ElseIf ScriptChar(j) = ")" Then '離開子查詢, 紀錄-1 // i -= 1 // ElseIf ScriptChar(j) = "g" Then 'where的起始點 // If j + 7 <= ScriptChar.Length - 1 Then // If strScript.Substring(j, 8) = "group by" AndAlso i <= 0 Then // blnHaveGroupBy = True // Exit For // End If // End If // Else '其他字元不處理 // End If // Next // If blnHaveGroupBy = False Then // intGroupBy = -1 // Else // intGroupBy = strScript.LastIndexOf("group by") // End If // End If // Else '一個group by都沒有 // intGroupBy = -1 // End If // If (strScript.LastIndexOf("order by") <> -1) Then '有order by,需要判斷 // If (strScript.Contains(")")) = False Then '沒有括弧,group by在最外層 // intOrderBy = strScript.LastIndexOf("order by") // Else '有括弧,判斷group by是否在最外層 // Dim blnHaveOrderBy As Boolean = False // Dim ScriptChar() As Char = strScript.ToCharArray // i = 0 // For j As Integer = 0 To ScriptChar.Length - 1 // If ScriptChar(j) = "(" Then '進入子查詢, 紀錄+1 // i += 1 // ElseIf ScriptChar(j) = ")" Then '離開子查詢, 紀錄-1 // i -= 1 // ElseIf ScriptChar(j) = "o" Then 'where的起始點 // If j + 7 <= ScriptChar.Length - 1 Then // If (strScript.Substring(j, 8) = "order by" AndAlso i <= 0) Then // blnHaveOrderBy = True // Exit For // End If // End If // Else '其他字元不處理 // End If // Next // If blnHaveOrderBy = False Then // intOrderBy = -1 // Else // intOrderBy = strScript.LastIndexOf("order by") // End If // End If // Else '一個order by都沒有 // intOrderBy = -1 // End If // If intGroupBy = -1 Then // If intOrderBy = -1 Then // 'Script中無GroupBy及OrderBy // strResult = pTable.Rows(0)("AlertScript").ToString & " " & strCondition // Else // Dim strOrderBy As String = Mid(strScript, strScript.LastIndexOf("order by")) // 'Script中無GroupBy但有OrderBy // strBody = Mid(pTable.Rows(0)("AlertScript").ToString, 1, Len(strScript) - Len(strOrderBy)) // strResult = strBody & " " & strCondition & " " & strOrderBy // End If // Else // Dim strGroupBy As String = Mid(pTable.Rows(0)("AlertScript").ToString, strScript.LastIndexOf("group by")) // 'Script中有GroupBy,並可能有OrderBy // strBody = Mid(pTable.Rows(0)("AlertScript").ToString, 1, Len(strScript) - Len(strGroupBy)) // strResult = strBody & " " & strCondition & " " & strGroupBy // End If // 2014/01/27, Hank, 以Select * From包原本語法再插入無特殊位置的條件式 strCondition = Strings.Replace(strCondition, "And", "Where", 1, 1); strResult = Conversions.ToString(Operators.ConcatenateObject(Operators.ConcatenateObject(Operators.ConcatenateObject("Select * From ( ", pTable.Rows[0]["AlertScript"]), " ) T "), strCondition)); return strResult; } #endregion #region AlertEventLog執行緒 /// /// 預警事件Log非同步作業開始 /// /// /// /// private void EventLog_DoWork(object sender, DoWorkEventArgs e) { string strSQL; AlertEvent ae = null; AutoRunLog result = null; AutoRunLog result2 = null; IDbConnection cn = null; IDbCommand cmd = null; IDbTransaction tx = null; DateTime dtAlertTime; try { result2 = new AutoRunLog(); result2.LogID = "N/A"; result2.AlertEventID = "EventLog_DoWork"; result2.AlertEventName = result2.AlertEventID; result2.StartTime = DateTime.Now; // 開啟資料庫連線 if (QueueEventLog.Count > 0) { cn = CreateConnection(dbi.RealDB.ConnectionString); //cn.Open(); cmd = CreateCommand("", cn); } while (QueueEventLog.Count > 0) { try { // 取出預警事件Log的第一筆, 並設定起始時間 ae = QueueEventLog[0]; result = new AutoRunLog(ae); tx = cn.BeginTransaction(); cmd.Transaction = tx; dtAlertTime = DateTime.Now; string FIELD01 = ""; string FIELD02 = ""; string FIELD03 = ""; string FIELD04 = ""; string FIELD05 = ""; string strAlertTime = ""; foreach (DataRow row in ae.ResultTable.Rows) { cmd.Parameters.Clear(); // 20221107,13871,0121824: 台基预警:预警频率不是设定的预警频率,固定的5分钟一预警,註解此 // cmd.Parameters.AddWithValue("LogID", ae.LogID) // cmd.Parameters.AddWithValue("AlertEventID", ae.AlertEventID & "") // cmd.Parameters.AddWithValue("AlertType", ae.AlertType) // cmd.Parameters.AddWithValue("AlertEventName", ae.AlertEventName & "") // cmd.Parameters.AddWithValue("AlertTime", dtAlertTime) // cmd.Parameters.AddWithValue("AlertDesc", ae.Description & "") // cmd.Parameters.AddWithValue("AlertCreator", ae.Creator & "") // cmd.Parameters.AddWithValue("FIELD01", "") // cmd.Parameters.AddWithValue("FIELD02", "") // cmd.Parameters.AddWithValue("FIELD03", "") // cmd.Parameters.AddWithValue("FIELD04", "") // cmd.Parameters.AddWithValue("FIELD05", "") switch (ae.AlertType) { case AlertTypeEnum.ERF: { // cmd.Parameters("FIELD01").Value = row("ERFNo").ToString FIELD01 = row["ERFNo"].ToString(); break; } case AlertTypeEnum.LOT: { // cmd.Parameters("FIELD01").Value = row("LotNo").ToString FIELD01 = row["LotNo"].ToString(); break; } case AlertTypeEnum.EQP: { // cmd.Parameters("FIELD01").Value = row("EquipmentNo").ToString FIELD01 = row["EquipmentNo"].ToString(); break; } case AlertTypeEnum.ACC: { // cmd.Parameters("FIELD01").Value = row("AccessoryNo").ToString FIELD01 = row["AccessoryNo"].ToString(); if (ae.ResultTable.Columns.Contains("AccessoryVersion")) { // cmd.Parameters("FIELD02").Value = row("AccessoryVersion").ToString FIELD02 = row["AccessoryVersion"].ToString(); } else { // cmd.Parameters("FIELD02").Value = "*" FIELD02 = "*"; } break; } case AlertTypeEnum.MO: { // cmd.Parameters("FIELD01").Value = row("MONo").ToString FIELD01 = row["MONo"].ToString(); break; } case AlertTypeEnum.PRD: { // cmd.Parameters("FIELD01").Value = row("ProductNo").ToString FIELD01 = row["ProductNo"].ToString(); if (ae.ResultTable.Columns.Contains("ProductVersion")) { // cmd.Parameters("FIELD02").Value = row("ProductVersion").ToString FIELD02 = row["ProductVersion"].ToString(); } else { // cmd.Parameters("FIELD02").Value = "*" FIELD02 = "*"; } break; } case AlertTypeEnum.OP: { // cmd.Parameters("FIELD01").Value = row("OPNo").ToString FIELD01 = row["OPNo"].ToString(); break; } } // 20221107,13871,0121824: 台基预警:预警频率不是设定的预警频率,固定的5分钟一预警 if (dbi.RealDB.DatabaseType.ToLower() != "oracle") { strAlertTime = "'" + Strings.Format(Conversions.ToDate(dtAlertTime), "yyyy/MM/dd H:mm:ss") + "'"; } else { strAlertTime = "To_Date('" + Strings.Format(Conversions.ToDate(dtAlertTime), "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')"; } // 20221107,13871,0121824: 台基预警:预警频率不是设定的预警频率,固定的5分钟一预警 strSQL = " Insert into tblIEWAlertEventLog " + " (LogID, AlertEventID, AlertType, AlertEventName, AlertTime, AlertDesc, AlertCreator, " + " FIELD01, FIELD02, FIELD03, FIELD04, FIELD05) Values " + string.Format(" ('{0}', '{1}', '{2}', '{3}', {4}, '{5}', '{6}', '{7}', '{8}', '{9}', '{10}', '{11}') ", ae.LogID, ae.AlertEventID, (int)ae.AlertType, ae.AlertEventName, strAlertTime, ae.Description, ae.Creator, FIELD01, FIELD02, FIELD03, FIELD04, FIELD05); cmd.CommandText = strSQL; cmd.ExecuteNonQuery(); //string cmdTmp = cmd.ToString(); } tx.Commit(); result.ExecuteResult = ExecuteResultEnum.SUCCESS; result.ErrorMessage = "寫入記錄成功"; } catch (Exception ex) { result.ExecuteResult = ExecuteResultEnum.FAIL; result.ErrorMessage = "寫入記錄失敗, " + ex.Message; if (tx != null) { tx.Rollback(); } } finally { if (result.ExecuteResult == ExecuteResultEnum.SUCCESS || result.ExecuteResult == ExecuteResultEnum.FAIL) { result.EndTime = DateTime.Now; QueueEventLog.Remove(ae); QueueAutoRunLog.Add(result); } if (tx != null) { tx = null; } } } result2 = null; } catch (Exception ex) { result2.EndTime = DateTime.Now; result2.ExecuteResult = ExecuteResultEnum.FAIL; result2.ErrorMessage = ex.Message; } finally { if (cn.State == ConnectionState.Open) { cn.Close(); cn = null; } if (cmd != null) { cmd = null; } e.Result = result2; } } /// /// 預警事件Log非同步作業結束 /// /// /// /// private void EventLog_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { AutoRunLog result = (AutoRunLog)e.Result; if (result != null && result.ExecuteResult == ExecuteResultEnum.FAIL) { QueueAutoRunLog.Add(result); } } #endregion #region AutoRunLog執行緒 /// /// AutoRunLog非同步作業開始 /// /// /// /// private void AutoRunLog_DoWork(object sender, DoWorkEventArgs e) { AutoRunLog log = null; AutoRunLog result2 = null; IDbConnection cn = null; IDbCommand cmd = null; DataTable dtLog = null; string strSQL = ""; string strReturnMsg = ""; try { result2 = new AutoRunLog(); result2.LogID = "N/A"; result2.AlertEventID = "AutoRunLog_DoWork"; result2.AlertEventName = result2.AlertEventID; result2.StartTime = DateTime.Now; // 開啟資料庫連線 if (QueueAutoRunLog.Count > 0) { cn = CreateConnection(dbi.RealDB.ConnectionString); //cn.Open(); cmd = CreateCommand("", cn); } while (QueueAutoRunLog.Count > 0) { try { log = QueueAutoRunLog[0]; // LogID存在 --> Append Message, LogID不存在 --> Insert Message strSQL = " Select * " + " From tblIEWAutoRunLog " + " Where LogID = '" + log.LogID + "'"; cmd.CommandText = strSQL; cmd.Parameters.Clear(); // 20221107,13871,0121824: 台基预警:预警频率不是设定的预警频率,固定的5分钟一预警,註解此 // cmd.Parameters.AddWithValue("LogID", log.LogID & "") //using (var da = new System.Data.OleDb.OleDbDataAdapter(cmd)) //{ dtLog = new DataTable(); //da.Fill(dtLog); ExecuteSQLQuery_Adapter(cmd, dtLog); //} if (dtLog.Rows.Count == 0 || log.LogID == "N/A") { // Insert //strSQL = " Insert into tblIEWAutoRunLog " + " (AlertEventID, AlertEventName, Status, StartTime, EndTime, RunTime, ReturnMsg, LogID) Values " + " (?, ?, ?, ?, ?, ?, ?, ?) "; strSQL = " Insert into tblIEWAutoRunLog " + " (AlertEventID, AlertEventName, Status, StartTime, EndTime, RunTime, ReturnMsg, LogID) Values " + " (:p1, :p2, :p3, :p4, :p5, :p6, :p7, :p8) "; strReturnMsg = Strings.Format(log.EndTime, "yyyy/MM/dd HH:mm") + ", " + log.ErrorMessage.ToString(); cmd.CommandText = strSQL; cmd.Parameters.Clear(); //cmd.Parameters.AddWithValue("AlertEventID", log.AlertEventID.ToString()); //cmd.Parameters.AddWithValue("AlertEventName", log.AlertEventName.ToString()); //cmd.Parameters.AddWithValue("Status", log.ExecuteResult.ToString()); //cmd.Parameters.AddWithValue("StartTime", log.StartTime); //cmd.Parameters.AddWithValue("EndTime", log.EndTime); //cmd.Parameters.AddWithValue("RunTime", DateAndTime.DateDiff(DateInterval.Second, log.StartTime, log.EndTime)); //cmd.Parameters.AddWithValue("ReturnMsg", strReturnMsg); //cmd.Parameters.AddWithValue("LogID", log.LogID.ToString()); AddCommandParameter(cmd, "p1", log.AlertEventID); AddCommandParameter(cmd, "p2", log.AlertEventName); AddCommandParameter(cmd, "p3", log.ExecuteResult); AddCommandParameter(cmd, "p4", log.StartTime); AddCommandParameter(cmd, "p5", log.EndTime); AddCommandParameter(cmd, "p6", DateAndTime.DateDiff(DateInterval.Second, log.StartTime, log.EndTime)); AddCommandParameter(cmd, "p7", strReturnMsg); AddCommandParameter(cmd, "p8", log.LogID); cmd.ExecuteNonQuery(); } else { // Append //strSQL = " Update tblIEWAutoRunLog " + " Set Status = ?, " + " EndTime = ?, " + " RunTime = ?, " + " ReturnMsg = ? " + " Where LogID = ? "; strSQL = " Update tblIEWAutoRunLog " + " Set Status = :p1, " + " EndTime = :p2, " + " RunTime = :p3, " + " ReturnMsg = :p4 " + " Where LogID = :p5 "; cmd.CommandText = strSQL; cmd.Parameters.Clear(); if (log.ExecuteResult == ExecuteResultEnum.FAIL) { //cmd.Parameters.AddWithValue("Status", log.ExecuteResult.ToString()); AddCommandParameter(cmd, "p1", log.ExecuteResult); } else { //cmd.Parameters.AddWithValue("Status", dtLog.Rows[0]["Status"]); AddCommandParameter(cmd, "p1", dtLog.Rows[0]["Status"]); } strReturnMsg = Strings.Format(log.EndTime, "yyyy/MM/dd HH:mm") + ", " + log.ErrorMessage.ToString(); if (Operators.ConditionalCompareObjectNotEqual(Operators.ConcatenateObject(dtLog.Rows[0]["ReturnMsg"], ""), "", false)) { strReturnMsg = Conversions.ToString(Operators.ConcatenateObject(Operators.ConcatenateObject(dtLog.Rows[0]["ReturnMsg"], Constants.vbCrLf), strReturnMsg)); } //cmd.Parameters.AddWithValue("EndTime", log.EndTime); //cmd.Parameters.AddWithValue("RunTime", DateAndTime.DateDiff(DateInterval.Second, Conversions.ToDate(dtLog.Rows[0]["StartTime"]), log.EndTime)); //cmd.Parameters.AddWithValue("ReturnMsg", strReturnMsg); //cmd.Parameters.AddWithValue("LogID", log.LogID.ToString()); AddCommandParameter(cmd, "p2", log.EndTime); AddCommandParameter(cmd, "p3", DateAndTime.DateDiff(DateInterval.Second, Conversions.ToDate(dtLog.Rows[0]["StartTime"]), log.EndTime)); AddCommandParameter(cmd, "p4", strReturnMsg); AddCommandParameter(cmd, "p5", log.LogID); cmd.ExecuteNonQuery(); } } catch (Exception ex) { log.ErrorMessage = log.ErrorMessage + Constants.vbCrLf + ex.Message; WriteToAnEventLog(log, EventLogEntryType.Error, 9000); } finally { QueueAutoRunLog.Remove(log); } } result2 = null; } catch (Exception ex) { result2.EndTime = DateTime.Now; result2.ExecuteResult = ExecuteResultEnum.FAIL; result2.ErrorMessage = ex.Message; } finally { if (cn.State == ConnectionState.Open) { cn.Close(); cn = null; } if (cmd != null) { cmd = null; } if (dtLog != null) { dtLog = null; } e.Result = result2; } } /// /// AutoRunLog非同步作業結束 /// /// /// /// private void AutoRunLog_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { AutoRunLog result = (AutoRunLog)e.Result; if (result != null && result.ExecuteResult == ExecuteResultEnum.FAIL) { WriteToAnEventLog(result, EventLogEntryType.Error, 9000); } } #endregion #region 派送執行緒 /// /// 派送非同步作業開始 /// /// /// /// /// Modify Notes:2016-06-02, Joe, 調整程式加MCloud推播功能 private void Delivery_DoWork(object sender, DoWorkEventArgs e) { AlertEvent ae = null; AutoRunLog result = null; AutoRunLog result2 = null; try { result2 = new AutoRunLog(); result2.LogID = "N/A"; result2.AlertEventID = "Delivery_DoWork"; result2.AlertEventName = result2.AlertEventID; result2.StartTime = DateTime.Now; while (QueueDelivery.Count > 0) { try { ae = QueueDelivery[0]; funWriteTxtFile(string.Format("Process Delivery.{2}{0}:{1}", ae.AlertEventID, ae.AlertEventName, Constants.vbCrLf)); result = new AutoRunLog(ae); // 2020/04/17 雋辰,修改Notice處理方式 string[] notices = ae.NoticeType.Split(','); var appNotices = new List(); foreach (string notice in notices) { if (notice == "0") { funSendMail(ref ae); } else if (notice == "3") { funSendMCloud(ref ae); } else if (notice == "4") { appNotices.Add("Line"); } else if (notice == "5") { appNotices.Add("WeChat"); } } if (appNotices.Count > 0) funSendApp(ref ae, appNotices); result.ExecuteResult = ExecuteResultEnum.SUCCESS; result.ErrorMessage = "派送事件成功"; } catch (Exception ex) { result.ExecuteResult = ExecuteResultEnum.FAIL; result.ErrorMessage = "派送事件失敗, " + ex.Message; } finally { if (result.ExecuteResult == ExecuteResultEnum.SUCCESS || result.ExecuteResult == ExecuteResultEnum.FAIL) { result.EndTime = DateTime.Now; QueueDelivery.Remove(ae); QueueAutoRunLog.Add(result); } } } } catch (Exception ex) { result2.EndTime = DateTime.Now; result2.ExecuteResult = ExecuteResultEnum.FAIL; result2.ErrorMessage = ex.Message; } finally { e.Result = result2; } } // 2016-05-31, Joe, 派送方式加MCloud推播 private void funSendMCloud(ref AlertEvent ae) { string pKey = ""; string pPushMsg = ""; string OutXml = ""; string strFrom = "SFT"; string strTargetUser = "DS"; string strAlert = ae.AlertEventName; string strKeyField = ""; try { // strTargetUser = GetAlertRecipients(ae) // 組XML,內容要以Base64加密 pPushMsg = ""; pPushMsg = pPushMsg + "" + strFrom + ""; pPushMsg = pPushMsg + "" + strTargetUser + ""; pPushMsg = pPushMsg + ""; pPushMsg = pPushMsg + "" + strAlert + ""; pPushMsg = pPushMsg + "" + strKeyField + ""; pPushMsg = pPushMsg + ""; pPushMsg = pPushMsg + ""; // Call MCloud Push Message Service using (var wsMCloud = new wsMCloud.PushService()) { OutXml = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(wsMCloud.PushDevicePMG(pKey, Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(pPushMsg))))); } // 利用XmlDoc物件處理ReturnValue var XmlDoc = new XmlDocument(); XmlDoc.LoadXml(OutXml); if (XmlDoc.DocumentElement["srvcode"].InnerXml != "000") { throw new Exception(XmlDoc.DocumentElement["srvmsg"].InnerXml); } } catch (Exception ex) { throw; } } private void funSendMail(ref AlertEvent ae) { // Dim mailserver As Net.Mail.SmtpClient = Nothing System.Net.Mail.MailMessage mail = null; Hashtable htSmtp = null; string bReturn = ""; int SecureSocketOptions = 1; try { // mailserver = New Net.Mail.SmtpClient mail = new System.Net.Mail.MailMessage(); htSmtp = new Hashtable(); // 取出SMTP的設定 //using (var da = new System.Data.OleDb.OleDbDataAdapter("Select * From tblSYSParameter Where ParameterType = 'SMTPInfo'", dbi.RealDB.ConnectionString)) //{ using (var dt = new DataTable()) { string strSQL = "Select * From tblSYSParameter Where ParameterType = 'SMTPInfo'"; //da.Fill(dt); ExecuteSQLQuery_Adapter(strSQL, dt, dbi.RealDB.ConnectionString, dbi.RealDB.DatabaseType); foreach (DataRow row in dt.Rows) htSmtp.Add(row["ParameterNo"], row["ParameterValue"]); } //} htSmtp["SMTPPassword"] = DeCrypt(htSmtp["SMTPPassword"].ToString()); // 0116180: 【晶睿】mes邮件服务器测试不成功,使用iMESMail套件 // mailserver.Credentials = New Net.NetworkCredential(htSmtp("SMTPUser").ToString, htSmtp("SMTPPassword").ToString) // mailserver.Port = Convert.ToInt32(htSmtp("SMTPPort")) // mailserver.Host = htSmtp("SMTPServer").ToString // '2019/05/08 Shih Kai, 根據參數:SMTPSSL(是否加密連線SSL),決定是否進行SSL加密 // If htSmtp("SMTPSSL").ToString = "1" Then // mailserver.EnableSsl = True // Else // mailserver.EnableSsl = False // End If // ' 寄件者 // mail.From = New System.Net.Mail.MailAddress(htSmtp("SYSEMail").ToString, htSmtp("SMTPUser").ToString, System.Text.Encoding.UTF8) // ' 主旨 // mail.Subject = ae.Subject // ' 收件者 var argmailto = mail.To; AddMailAddress(ae, ref argmailto); // ' 內文 // ' 內文-表頭 var mailcontent = new EmailContent(); mailcontent.AlertEventName = ae.AlertEventName; mailcontent.AlertType = ae.AlertType; mailcontent.AlertTime = DateTime.Now; mailcontent.AlertDescription = ae.Description; foreach (DataColumn col in ae.ResultTable.Columns) mailcontent.thead.Add(col.ColumnName); // 內文-表身 foreach (DataRow row in ae.ResultTable.Rows) { var tr = new EmailContent.tr(); foreach (DataColumn col in ae.ResultTable.Columns) tr.Add(row[col.ColumnName].ToString()); mailcontent.tbody.Add(tr); } // mail.IsBodyHtml = True // mail.Body = mailcontent.Generate // ' 發信 // mailserver.Send(mail) var EmailAddress = new Collection(); foreach (System.Net.Mail.MailAddress item in mail.To) EmailAddress.Add(item.Address); try { SecureSocketOptions = Conversions.ToInteger(htSmtp["SMTPSSL"].ToString()); } catch (Exception ex) { } // 0116180: 【晶睿】mes邮件服务器测试不成功,使用iMESMail套件 iMESCore.Mail.iMESMail.Send(htSmtp["SMTPServer"].ToString(), Convert.ToInt32(htSmtp["SMTPPort"]), htSmtp["SYSEMail"].ToString(), "", htSmtp["SMTPUser"].ToString(), htSmtp["SMTPPassword"].ToString(), SecureSocketOptions, ae.Subject, mailcontent.Generate(), EmailAddress); } catch (Exception ex) { throw; } finally { // mailserver = Nothing mail = null; htSmtp = null; } } /// /// 2020/04/17 雋辰,發送app訊息 /// /// /// private void funSendApp(ref AlertEvent ae, List pipe) { var objMDS = new kcWIP.clsMDS(); try { string message = ""; string lBreak = @"\n"; // 主旨 message = string.Format($"IEW 警示事件:{ae.Subject}{lBreak}{lBreak}"); // 內容 message += string.Format($"警示事件名稱:{ae.AlertEventName}{lBreak}{lBreak}警示類別:{ae.AlertType}{lBreak}{lBreak}警示時間:{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}{lBreak}{lBreak}說明:{ae.Description}{lBreak}{lBreak}"); // 表格 var tab = new Dictionary(); foreach (DataColumn col in ae.ResultTable.Columns) { tab[col.ColumnName] = ""; foreach (DataRow row in ae.ResultTable.Rows) { if (col.ColumnName.ToUpper() == "STARTTIME" && Information.IsDate(row[col.ColumnName].ToString())) { tab[col.ColumnName] += Conversions.ToDate(row[col.ColumnName].ToString()).ToString("yyyy/MM/dd HH:mm:ss") + ","; } else { tab[col.ColumnName] += row[col.ColumnName].ToString() + ","; } } tab[col.ColumnName] = tab[col.ColumnName].TrimEnd(','); } foreach (string key in tab.Keys) { if (string.IsNullOrEmpty(tab[key])) continue; message += string.Format($"{key}:{tab[key]}{lBreak}"); } objMDS.invoke_Message_Platform(AppSettings["MSG_SERVICE"].ToString(), objMDS.Create_MsgPlatform_Request("ServicesSTD.Module_MSG.send_notification_process", ae.Creator, message, Get_Users(ae), pipe)); } catch (Exception ex) { throw; } } /// /// 派送非同步作業結束 /// /// /// /// private void Delivery_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { AutoRunLog result = (AutoRunLog)e.Result; if (result != null && result.ExecuteResult == ExecuteResultEnum.FAIL) { QueueAutoRunLog.Add(result); } } #endregion #region 事件檢視器 /// /// 寫到 Windows Event Log /// /// private void WriteToAnEventLog(EventBase e, EventLogEntryType pEventType = EventLogEntryType.Information, int pEventID = 0) { string strSource = "MES IEW Service"; string strLog = "Application"; string strMessage = ""; try { if (!EventLog.SourceExists(strSource)) { EventLog.CreateEventSource(strSource, strLog); } strMessage = "AlertEvent: " + e.AlertEventID + Constants.vbCrLf + "StartTime: " + Strings.Format(e.StartTime, "yyyy/MM/dd HH:mm:ss") + Constants.vbCrLf + "EndTime: " + Strings.Format(e.EndTime, "yyyy/MM/dd HH:mm:ss") + Constants.vbCrLf + "ErrorMessage: " + e.ErrorMessage; funWriteTxtFile(strMessage); EventLog.WriteEntry(strSource, strMessage, pEventType, pEventID); } catch (Exception ex) { } } #endregion #region 預警事件的最後執行時間 private void WriteLastRunTime(AutoRunLog result) { string strSQL = ""; try { // 20221107,13871,0121824: 台基预警:预警频率不是设定的预警频率,固定的5分钟一预警 string strEndTime = ""; if (dbi.RealDB.DatabaseType.ToLower() != "oracle") { strEndTime = "'" + Strings.Format(Conversions.ToDate(result.EndTime), "yyyy/MM/dd H:mm:ss") + "'"; } else { strEndTime = "To_Date('" + Strings.Format(Conversions.ToDate(result.EndTime), "yyyy/MM/dd H:mm:ss") + "','YYYY/MM/DD HH24:MI:SS')"; } strSQL = " Update tblIEWAlertEventBasis " + " Set LastRunTime = " + strEndTime + " Where AlertEventID = '" + result.AlertEventID + "'"; //using (var cn = CreateConnection(dbi.RealDB.ConnectionString)) //{ // using (var cmd = CreateCommand(strSQL, cn)) // { // //cn.Open(); // // 20221107,13871,0121824: 台基预警:预警频率不是设定的预警频率,固定的5分钟一预警,註解此 // // cmd.Parameters.AddWithValue("LastRunTime", result.EndTime) // // cmd.Parameters.AddWithValue("AlertEventID", result.AlertEventID) // cmd.ExecuteNonQuery(); // cn.Close(); // } //} ExecuteSQLNoneQuery(dbi.RealDB.DatabaseType, dbi.RealDB.ConnectionString, ref strSQL); } catch (Exception ex) { } finally { } } #endregion #region 加入收件者 /// /// 依警示事件編號取回收件人, 若無收件人, 則以預警事件的建立人為收件人 /// /// private void AddMailAddress(AlertEvent ae, ref System.Net.Mail.MailAddressCollection mailto) { string strSQL; IDbConnection cn = null; //IDbCommand cmd = null; DataTable dtTemp = null; try { // 2014/01/24, Hank, 預警事件的建立人也要發送 strSQL = " Select EmailAddress From tblUSRUserBasis " + " Where UserNo = '" + ae.Creator + "' " + " And EmailAddress is not null " + " Union " + " Select B.EmailAddress " + " From tblIEWAlertRecipients A, tblUSRUserBasis B " + " Where A.Recipient = B.UserNo " + " And A.AlertEventID = '" + ae.AlertEventID + "' " + " And A.RecipientType = 99 " + " And B.IssueState = 2 " + " And B.EmailAddress is not null " + " Union " + " Select C.EmailAddress " + " From tblIEWAlertRecipients A, tblUSRUserGroup B, tblUSRUserBasis C " + " Where A.Recipient = B.GroupNo " + " And A.RecipientType = B.GroupType " + " And B.UserNo = C.UserNo " + " And A.AlertEventID = '" + ae.AlertEventID + "' " + " And A.RecipientType <> 99 " + " And C.EmailAddress is not null "; cn = CreateConnection(dbi.RealDB.ConnectionString); //cn.Open(); //cmd = CreateCommand(strSQL, cn); //using (var da = new System.Data.OleDb.OleDbDataAdapter(cmd)) //{ // dtTemp = new DataTable(); // da.Fill(dtTemp); //} ExecuteSQLQuery_Adapter(strSQL, dtTemp, cn); foreach (DataRow row in dtTemp.Rows) mailto.Add(row["EmailAddress"].ToString()); if (mailto.Count == 0) { throw new Exception("無任何收件人資訊!"); } } // If (dtTemp.Rows.Count = 0) Then // ' 若無收件人, 則以預警事件的建立人為收件人 // strSQL = " Select EmailAddress From tblUSRUserBasis Where UserNo = '" & di.Creator & "' " // cmd.CommandText = strSQL // If (cmd.ExecuteScalar.ToString & "" = "") Then // Throw New Exception("無任何收件人資訊!") // Else // mailto.Add(cmd.ExecuteScalar.ToString) // End If // Else // For Each row As DataRow In dtTemp.Rows // mailto.Add(row("EmailAddress").ToString) // Next // End If catch (Exception ex) { throw; } finally { if (cn != null && cn.State == ConnectionState.Open) { cn.Close(); cn.Dispose(); cn = null; } //if (cmd != null) //{ // cmd.Dispose(); // cmd = null; //} if (dtTemp != null) { dtTemp.Dispose(); dtTemp = null; } } } /// /// 2020/04/17 雋辰,取得需要發送的UserNo /// /// /// private List Get_Users(AlertEvent ae) { string strSQL; IDbConnection cn = null; //IDbCommand cmd = null; DataTable dtTemp = null; var result = new List(); try { // 2014/01/24, Hank, 預警事件的建立人也要發送 strSQL = " Select UserNo From tblUSRUserBasis " + " Where UserNo = '" + ae.Creator + "' " + " And UserNo is not null " + " Union " + " Select B.UserNo" + " From tblIEWAlertRecipients A, tblUSRUserBasis B " + " Where A.Recipient = B.UserNo " + " And A.AlertEventID = '" + ae.AlertEventID + "' " + " And A.RecipientType = 99 " + " And B.IssueState = 2 " + " And B.UserNo is not null " + " Union " + " Select C.UserNo" + " From tblIEWAlertRecipients A, tblUSRUserGroup B, tblUSRUserBasis C " + " Where A.Recipient = B.GroupNo " + " And A.RecipientType = B.GroupType " + " And B.UserNo = C.UserNo " + " And A.AlertEventID = '" + ae.AlertEventID + "' " + " And A.RecipientType <> 99 " + " And C.UserNo is not null "; cn = CreateConnection(dbi.RealDB.ConnectionString); //cn.Open(); //cmd = CreateCommand(strSQL, cn); //using (var da = new System.Data.OleDb.OleDbDataAdapter(cmd)) //{ // dtTemp = new DataTable(); // da.Fill(dtTemp); //} ExecuteSQLQuery_Adapter(strSQL, dtTemp, cn); foreach (DataRow row in dtTemp.Rows) { if (!result.Contains(row["UserNo"].ToString())) result.Add(row["UserNo"].ToString()); } if (result.Count == 0) { throw new Exception(string.Format($"無任何接收者資訊")); } return result; } catch (Exception ex) { throw; } finally { if (cn != null && cn.State == ConnectionState.Open) { cn.Close(); cn.Dispose(); cn = null; } //if (cmd != null) //{ // cmd.Dispose(); // cmd = null; //} if (dtTemp != null) { dtTemp.Dispose(); dtTemp = null; } } } // 2016-06-02, Joe, Add private string GetAlertRecipients(AlertEvent ae) { string GetAlertRecipientsRet = default(string); string strSQL; IDbConnection cn = null; //IDbCommand cmd = null; DataTable dtTemp = null; string strReturn = ""; try { strSQL = " Select A.* " + " From tblIEWAlertRecipients A " + " Where A.AlertEventID = '" + ae.AlertEventID + "' " + " And A.RecipientType <> 99 "; cn = CreateConnection(dbi.RealDB.ConnectionString); //cn.Open(); //cmd = CreateCommand(strSQL, cn); //using (var da = new System.Data.OleDb.OleDbDataAdapter(cmd)) //{ // dtTemp = new DataTable(); // da.Fill(dtTemp); //} ExecuteSQLQuery_Adapter(strSQL, dtTemp, cn); foreach (DataRow row in dtTemp.Rows) { if (string.IsNullOrEmpty(strReturn)) { strReturn = row["RECIPIENT"].ToString(); } else { strReturn = strReturn + "├" + row["RECIPIENT"].ToString(); } } if (string.IsNullOrEmpty(strReturn)) { throw new Exception("無任何警示群組資訊!"); } } catch (Exception ex) { throw; } finally { if (cn != null && cn.State == ConnectionState.Open) { cn.Close(); cn.Dispose(); cn = null; } //if (cmd != null) //{ // cmd.Dispose(); // cmd = null; //} if (dtTemp != null) { dtTemp.Dispose(); dtTemp = null; } GetAlertRecipientsRet = strReturn; } return GetAlertRecipientsRet; } #endregion #region Other Class /// /// 警示事件主檔 /// /// private class AlertEvent : EventBase, IEquatable { public AlertEventTypeEnum AlertEventType; // 警示事件類型 0:Default(預設事件) 1:Custom(自定義事件) public string AlertEventSource; // 警示事件來源(警示編號/預設事件ID) public string NoticeType; // 警示通知方式 '0':Email(郵件) '1':SMS(簡訊) '0,1':EMail+SMS(郵件+簡訊) '2':MCloud(推播) public string Subject; // 訊息主旨 public string Description; // 說明 public string Creator; // 建立人 public DataTable ResultTable; public AlertEvent(DataRow row) { AlertEventID = row["AlertEventID"].ToString(); AlertEventName = row["AlertEventName"].ToString(); AlertEventType = (AlertEventTypeEnum)Conversions.ToInteger(row["AlertEventType"]); AlertEventSource = row["AlertEventSource"].ToString(); NoticeType = row["NoticeType"].ToString(); Subject = row["Subject"].ToString(); Description = row["Description"].ToString(); Creator = row["Creator"].ToString(); } // 判斷是否有相同的警示事件編號 public bool Equals(AlertEvent other) { if ((AlertEventID ?? "") == (other.AlertEventID ?? "")) { return true; } else { return false; } } } // ''' // ''' 警示事件結果記錄表(Log) // ''' // ''' // Private Class AlertEventLog // Inherits EventBase // Public AlertTime As Date ' 警示時間 // Public AlertDesc As String ' 說明 // Public AlertCreator As String ' 警示建立人 // Public AlertResult As DataTable ' 警示事件觸發結果 // Public Sub New() // Me.Worker = WorkerEnum.ALERTEVENTLOG // End Sub // Public Sub New(ae As AlertEvent, pAlertResult As DataTable) // Me.AlertEventID = ae.AlertEventID // Me.AlertEventName = ae.AlertEventName // Me.AlertType = ae.AlertType // Me.AlertTime = Now // Me.AlertDesc = ae.Description // Me.AlertCreator = ae.Creator // Me.AlertResult = pAlertResult // Me.Worker = WorkerEnum.ALERTEVENTLOG // End Sub // End Class /// /// AutoRun Log /// /// private class AutoRunLog : EventBase { public AutoRunLog() { } public AutoRunLog(AlertEvent ae) { LogID = ae.LogID; AlertEventID = ae.AlertEventID; AlertEventName = ae.AlertEventName; StartTime = DateTime.Now; } // Public Sub New(ael As AlertEventLog) // Me.AlertEventID = ael.AlertEventID // Me.AlertEventName = ael.AlertEventName // Me.StartTime = ael.StartTime // Me.EndTime = ael.EndTime // Me.ExecuteResult = ael.ExecuteResult // Me.ErrorMessage = ael.ErrorMessage // Me.Worker = ael.Worker // End Sub // Public Sub New(di As DeliveryInfo) // Me.AlertEventID = di.AlertEventID // Me.AlertEventName = di.AlertEventName // Me.StartTime = di.StartTime // Me.EndTime = di.EndTime // Me.ExecuteResult = di.ExecuteResult // Me.ErrorMessage = di.ErrorMessage // Me.Worker = di.Worker // End Sub } /// /// Base /// /// private abstract class EventBase { public string LogID; public string AlertEventID; // 警示事件ID public string AlertEventName; // 警示事件名稱 public DateTime StartTime; // 事件開始時間 public DateTime EndTime; // 事件結束時間 public ExecuteResultEnum ExecuteResult; // 執行結果 public string ErrorMessage; // 錯誤訊息 public AlertTypeEnum AlertType; // 警示類型 1:ERF, 2:LOT, 3:EQP, 4:ACC, 5:MO } // ''' // ''' 派送資訊 // ''' // ''' // Private Class DeliveryInfo // Inherits EventBase // Public Subject As String ' 訊息主旨 // Public Description As String ' 說明 // Public Creator As String ' 預警事件建立者, 若AlertEventID無對應的收件人, 則以此為收件人 // Public AlertContent As DataTable ' 訊息內容 // Public Sub New() // Me.Worker = WorkerEnum.DELIVERY // End Sub // Public Sub New(ae As AlertEvent, pAlertContent As DataTable) // Me.AlertEventID = ae.AlertEventID // Me.AlertEventName = ae.AlertEventName // Me.AlertType = ae.AlertType // Me.Subject = ae.Subject // Me.Description = ae.Description // Me.Creator = ae.Creator // Me.AlertContent = pAlertContent // Me.Worker = WorkerEnum.DELIVERY // End Sub // End Class /// /// Email內容 /// /// private class EmailContent { #region tr public class tr : IList { private List listTR = new List(); public void Add(string item) { listTR.Add(item); } public void Clear() { listTR.Clear(); } public bool Contains(string item) { return listTR.Contains(item); } public void CopyTo(string[] array, int arrayIndex) { } public int Count { get { return listTR.Count; } } public bool IsReadOnly { get { return false; } } public bool Remove(string item) { return listTR.Remove(item); } public IEnumerator GetEnumerator() { return listTR.GetEnumerator(); } public int IndexOf(string item) { return listTR.IndexOf(item); } public void Insert(int index, string item) { listTR.Insert(index, item); } public string this[int index] { get { return listTR[index]; } set { listTR[index] = value; } } public void RemoveAt(int index) { listTR.RemoveAt(index); } public IEnumerator GetEnumerator1() { return listTR.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator1(); } #endregion public string AlertEventName; // 警示事件名稱 public AlertTypeEnum AlertType; // 警示類別 public DateTime AlertTime; // 警示時間 public string AlertDescription; // 說明 public List thead = new List(); public List tbody = new List(); public string Generate() { int idx = 0; string strTemp = ""; string strContent = ""; strContent += "
警示事件名稱: " + AlertEventName + "

"; strContent += "
警示類別: " + AlertType.ToString() + "

"; strContent += "
警示時間: " + Conversions.ToString(AlertTime) + "

"; strContent += "
說明: " + AlertDescription + "

"; // header strContent += ""; strContent += ""; foreach (string s in thead) { strContent += ""; } strContent += ""; // body foreach (tr r in tbody) { idx += 1; if (idx % 2 == 1) { // 奇數列 strContent += ""; } else { // 偶數列 strContent += ""; } strTemp = ""; foreach (string d in r) { strTemp += ""; } strContent += strTemp; strContent += ""; } strContent += "
"; strContent += s; strContent += "
"; strTemp += d; strTemp += "
"; return strContent; } } #endregion #region 資料庫物件 private class DatabaseInfo { public struct DatabaseProperty { public string DatabaseType; public string DatabaseOwner; public string DatabasePassword; public string ConnectionString; } public DatabaseProperty RealDB = new DatabaseProperty(); public DatabaseProperty HistoryDB = new DatabaseProperty(); public DatabaseInfo() { iMESLicxManager.clsDecoding objLicMag = new iMESLicxManager.clsDecoding(); try { RealDB.DatabaseType = AppSettings["DatabaseType"]; RealDB.DatabaseOwner = AppSettings["DatabaseOwner"]; RealDB.DatabasePassword = objLicMag.PasswordDecoding(AppSettings["DatabasePassword"]); RealDB.ConnectionString = AppSettings["ConnectionString"] + ";Password=" + RealDB.DatabasePassword; HistoryDB.DatabaseType = AppSettings["ReportDatabaseType"]; HistoryDB.DatabaseOwner = AppSettings["ReportDatabaseOwner"]; HistoryDB.DatabasePassword = objLicMag.PasswordDecoding(AppSettings["ReportDatabasePassword"]); HistoryDB.ConnectionString = AppSettings["ReportConnectionString"] + ";Password=" + HistoryDB.DatabasePassword; } catch (Exception ex) { throw; } finally { objLicMag = null; } } } #endregion #region 解密 // 對應的解密,中文字解碼有問題 public string DeCrypt(string strCryptThis) { string DeCryptRet = default(string); string g_Key = "xNDFz6LH67LOv7xKbWFpbMu1wejrM7SzvV4tLRvq3X47m708O1xMHLoaMNCqGhoaEN"; int iDeCryptChar; string strDecrypted = ""; int i, iKeyChar, iStringChar; try { strCryptThis = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(strCryptThis)); var loopTo = Strings.Len(strCryptThis); for (i = 1; i <= loopTo; i++) { iKeyChar = Strings.Asc(Strings.Mid(g_Key, i, 1)); iStringChar = Strings.Asc(Strings.Mid(strCryptThis, i, 1)); iDeCryptChar = iKeyChar ^ iStringChar; strDecrypted = strDecrypted + Strings.Chr(iDeCryptChar); } DeCryptRet = strDecrypted; } catch (Exception ex) { throw; } return DeCryptRet; } #endregion #region Queue private class IEWQueue : IList { public event AddCompleteEventHandler AddComplete; public delegate void AddCompleteEventHandler(); private List q = new List(); public void Add(T item) { q.Add(item); AddComplete?.Invoke(); } public void Clear() { q.Clear(); } public bool Contains(T item) { return q.Contains(item); } public void CopyTo(T[] array, int arrayIndex) { q.CopyTo(array, arrayIndex); } public int Count { get { return q.Count; } } public bool IsReadOnly { get { return false; } } public bool Remove(T item) { return q.Remove(item); } public IEnumerator GetEnumerator() { return q.GetEnumerator(); } public int IndexOf(T item) { return q.IndexOf(item); } public void Insert(int index, T item) { q.Insert(index, item); } public T this[int index] { get { return q[index]; } set { q[index] = value; } } public void RemoveAt(int index) { q.RemoveAt(index); } public IEnumerator GetEnumerator1() { return q.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator1(); } #endregion #region AddComplete Event private void QueueEvent_AddComplete() { if (!WorkerEvent.IsBusy) { WorkerEvent.RunWorkerAsync(); } } private void QueueEventLog_AddComplete() { if (!WorkerEventLog.IsBusy) { WorkerEventLog.RunWorkerAsync(); } } private void QueueAutoRunLog_AddComplete() { if (!WorkerAutoRunLog.IsBusy) { WorkerAutoRunLog.RunWorkerAsync(); } } private void QueueDelivery_AddComplete() { if (!WorkerDelivery.IsBusy) { WorkerDelivery.RunWorkerAsync(); } } #endregion private int funWriteTxtFile(string WriteTxt, Exception ex = null) { int funWriteTxtFileRet = default(int); funWriteTxtFileRet = -1; try { if (logger != null) { logger.WriteLog(WriteTxt, iMESLog.iMESLogLevel.Info, ex); } else { if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + @"\Log")) { Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + @"\Log"); } var fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + @"\Log\MESIEW_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; } } }