2824 lines
105 KiB
C#
2824 lines
105 KiB
C#
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 Notes:2016-06-02, Joe, 調整程式加MCloud推播功能
|
||
private void Delivery_DoWork(object sender, DoWorkEventArgs e)
|
||
{
|
||
|
||
|
||
AlertEvent ae = null;
|
||
AutoRunLog result = null;
|
||
AutoRunLog result2 = null;
|
||
|
||
try
|
||
{
|
||
|
||
result2 = new AutoRunLog();
|
||
result2.LogID = "N/A";
|
||
result2.AlertEventID = "Delivery_DoWork";
|
||
result2.AlertEventName = result2.AlertEventID;
|
||
result2.StartTime = DateTime.Now;
|
||
|
||
while (QueueDelivery.Count > 0)
|
||
{
|
||
try
|
||
{
|
||
|
||
ae = QueueDelivery[0];
|
||
|
||
funWriteTxtFile(string.Format("Process Delivery.{2}{0}:{1}", ae.AlertEventID, ae.AlertEventName, Constants.vbCrLf));
|
||
|
||
result = new AutoRunLog(ae);
|
||
|
||
// 2020/04/17 雋辰,修改Notice處理方式
|
||
string[] notices = ae.NoticeType.Split(',');
|
||
var appNotices = new List<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;
|
||
|
||
}
|
||
}
|
||
} |