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
2024-01-18 14:03:02 +08:00

2824 lines
105 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}