This repo is archived. You can view files and clone it, but cannot push or open issues or pull requests.
SXS20240115/SRC/MESAgent/MESIEW/IEWService/IEWService.cs

2824 lines
105 KiB
C#
Raw Normal View History

2024-01-18 14:03:02 +08:00
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<AlertEvent> _QueueEvent;
private IEWQueue<AlertEvent> 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<AlertEvent> _QueueEventLog;
private IEWQueue<AlertEvent> 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<AutoRunLog> _QueueAutoRunLog;
private IEWQueue<AutoRunLog> 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<AlertEvent> _QueueDelivery;
private IEWQueue<AlertEvent> 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<AlertEvent>(); // 預警事件Queue, 符合執行週期的事件會放入此Queue
QueueEventLog = new IEWQueue<AlertEvent>(); // 預警事件Log Queue, 預警事件執行後, 將觸發結果放入此Queue
QueueAutoRunLog = new IEWQueue<AutoRunLog>(); // AutoRunLog Queue, 預警事件執行後, 將要Log的資料放入此Queue
QueueDelivery = new IEWQueue<AlertEvent>(); // 派送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
/// <summary>
/// 取出符合執行週期的預警事件
/// </summary>
/// <remarks></remarks>
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
/// <summary>
/// 主執行緒非同步作業開始, 用來啟動其它執行緒
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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;
}
}
/// <summary>
/// 主執行緒非同步作業結束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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執行緒
/// <summary>
/// 預警事件Queue非同步作業開始
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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;
}
}
/// <summary>
/// 預警事件Queue非同步作業結束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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
/// <summary>
/// 執行預警事件非同步執行作業開始
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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;
}
}
/// <summary>
/// 預警事件非同步執行作業結束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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);
}
/// <summary>
/// 產生SQL語法
/// </summary>
/// <param name="pTable"></param>
/// <returns></returns>
/// <remarks></remarks>
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執行緒
/// <summary>
/// 預警事件Log非同步作業開始
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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;
}
}
/// <summary>
/// 預警事件Log非同步作業結束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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執行緒
/// <summary>
/// AutoRunLog非同步作業開始
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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;
}
}
/// <summary>
/// AutoRunLog非同步作業結束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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
/// <summary>
/// 派送非同步作業開始
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
/// Modify Notes2016-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<string>();
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 = "<PushMsg>";
pPushMsg = pPushMsg + "<From>" + strFrom + "</From>";
pPushMsg = pPushMsg + "<TargetUser>" + strTargetUser + "</TargetUser>";
pPushMsg = pPushMsg + "<Message>";
pPushMsg = pPushMsg + "<alert>" + strAlert + "</alert>";
pPushMsg = pPushMsg + "<keyfield>" + strKeyField + "</keyfield>";
pPushMsg = pPushMsg + "</Message>";
pPushMsg = pPushMsg + "</PushMsg>";
// 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;
}
}
/// <summary>
/// 2020/04/17 雋辰,發送app訊息
/// </summary>
/// <param name="ae"></param>
/// <param name="pipe"></param>
private void funSendApp(ref AlertEvent ae, List<string> 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<string, string>();
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;
}
}
/// <summary>
/// 派送非同步作業結束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <remarks></remarks>
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
/// <summary>
/// 寫到 Windows Event Log
/// </summary>
/// <remarks></remarks>
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
/// <summary>
/// 依警示事件編號取回收件人, 若無收件人, 則以預警事件的建立人為收件人
/// </summary>
/// <remarks></remarks>
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;
}
}
}
/// <summary>
/// 2020/04/17 雋辰,取得需要發送的UserNo
/// </summary>
/// <param name="ae"></param>
/// <returns></returns>
private List<string> Get_Users(AlertEvent ae)
{
string strSQL;
IDbConnection cn = null;
//IDbCommand cmd = null;
DataTable dtTemp = null;
var result = new List<string>();
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
/// <summary>
/// 警示事件主檔
/// </summary>
/// <remarks></remarks>
private class AlertEvent : EventBase, IEquatable<AlertEvent>
{
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;
}
}
}
// ''' <summary>
// ''' 警示事件結果記錄表(Log)
// ''' </summary>
// ''' <remarks></remarks>
// 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
/// <summary>
/// AutoRun Log
/// </summary>
/// <remarks></remarks>
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
}
/// <summary>
/// Base
/// </summary>
/// <remarks></remarks>
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
}
// ''' <summary>
// ''' 派送資訊
// ''' </summary>
// ''' <remarks></remarks>
// 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
/// <summary>
/// Email內容
/// </summary>
/// <remarks></remarks>
private class EmailContent
{
#region tr
public class tr : IList<string>
{
private List<string> listTR = new List<string>();
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<string> 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<string> thead = new List<string>();
public List<tr> tbody = new List<tr>();
public string Generate()
{
int idx = 0;
string strTemp = "";
string strContent = "";
strContent += "<div style='font-size: 16px;'>警示事件名稱: " + AlertEventName + "</div><br />";
strContent += "<div style='font-size: 16px;'>警示類別: " + AlertType.ToString() + "</div><br />";
strContent += "<div style='font-size: 16px;'>警示時間: " + Conversions.ToString(AlertTime) + "</div><br />";
strContent += "<div style='font-size: 16px;'>說明: " + AlertDescription + "</div><br />";
// header
strContent += "<table width='100%' border='1' cellspacing='0' style='border: 1px solid #4472C4;'>";
strContent += "<tr style='background-color: #4472C4; color: white; height: 24px;'>";
foreach (string s in thead)
{
strContent += "<th style='font-weight: normal; border: 1px solid #DDDDDD;'>";
strContent += s;
strContent += "</th>";
}
strContent += "</tr>";
// body
foreach (tr r in tbody)
{
idx += 1;
if (idx % 2 == 1)
{
// 奇數列
strContent += "<tr style='height: 24px;'>";
}
else
{
// 偶數列
strContent += "<tr style='background-color: #D9E2F3; height: 24px;'>";
}
strTemp = "";
foreach (string d in r)
{
strTemp += "<td style='border: 1px solid #DDDDDD;'>";
strTemp += d;
strTemp += "</td>";
}
strContent += strTemp;
strContent += "</tr>";
}
strContent += "</table>";
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<T> : IList<T>
{
public event AddCompleteEventHandler AddComplete;
public delegate void AddCompleteEventHandler();
private List<T> q = new List<T>();
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<T> 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;
}
}
}