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