先說一下這個項目做了什麼。先介紹一下背景(備注一下,每次項目發生更改之後,要進行clean 和rebuild兩個操作,否則最新的更改保存不到exe文件中,這樣上線後的系統還是執行得原有的已編譯過的程序代碼,所以得出的結論就是在上線測試階段,對於程序代碼的每一次更改都要rebuild操作,來保證每次的更改作用於exe文件,保證編譯是最新的;;)
上面這個流程圖介紹了當我們需要take training follow-up的時候,我們需要在sharepoint Desinger中設置工作流,來完成這些功能,但是現在遇到一個問題,workflow的觸發是由於登錄頁面的用戶log一條item記錄的時候觸發的,如果我們要實現郵件的定時提醒功能,那麼就需要在每天都觸發執行一次workflow,但是由誰來觸發呢?剛開始網上搜了很多資料,內網 外網資料都搜了一圈,好不容易看到一個帖子說可以實現,但最後試著用workflow來解決,但是始終行不通,就算讓它執行個15分鐘,過了會兒就會掛掉。我估計系統可能開著這個線程太占用系統資源了。最終逼不得已才決定使用web service來解決這個問題,但是問題又來了,對於Java還算了解,但是對C#還是完全陌生,如果采用C#來做這個定時發送郵件的功能的話,帶來的risk無法估量,而且極有可能造成project的delay,所以在前期的決策上,試著采用了Java做了一部分調研,但是考慮到公司的sharepoint是部署位置及其Java與windows底層通信協議可能帶來的risk:項目進行到後期,極有可能無法完成,所以最終決定用C#來實現這個功能。。
該學習的技術還是要學的,你越逃避的事情,它越會找上你。所以,學習新技術也要趁早,等你的項目中需要用到的時候,你已經可以游刃有余了。
如上,為C#程序中要實現的邏輯。程序的整體實現邏輯是這樣的。我們取出list列表,然後進行過濾,當滿足我們的要求的時候,我們發郵件,然後做一些異常處理。Servic.cs代碼如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks; using System.Net; using System.Xml; using System.Timers; using System.Configuration; //using System.Web.Mail; using System.Net.Mail; namespace SharePointWorklow { public partial class Service1 : ServiceBase { //static private long FIVE_DAYS = 432000000L; public Service1() { InitializeComponent(); } public void Debug(string[] args) { this.OnStart(args); } protected override void OnStart(string[] args) { //Debugger.Launch(); System.Timers.Timer TimeCheck = new System.Timers.Timer(); TimeCheck.Interval = Double.Parse(ConfigurationSettings.AppSettings["INTERVAL"]); //TimeCheck.Interval = 60000; TimeCheck.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick); TimeCheck.AutoReset = true; TimeCheck.Enabled = true; timer1_Tick(this, ElapsedEventArgs.Empty); TimeCheck.Start(); } public static String MailBody(XmlNode node, Double delayDays) { String URL = @"http://ent261.sharepoint.hp.com/teams/jupiter_2/Lists/Training%20Record%20FY14/MyItems.aspx"; String start = "Congratulations for completing your training course: \n\nCourse Name: " + node.Attributes["ows_LinkTitle"].Value + ";\n"; String time = "Time: " + node.Attributes["ows_CreateTime"].Value; if (node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"] != null) { time = "From: " + node.Attributes["ows_CreateTime"].Value + "; \nTo: " + node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value + ";\n\n"; } String mention = "We mentioned you have not finished your follow-up with your PL for " + (int)delayDays + " days.\n"; String end = "Please check this link for finishing the following up of this course: \n"; String mailBody = start + time + mention + end + URL; return mailBody; } /* public static void SendE_Mail(XmlNode node, Double day, String name, String ccName, String fromName) { String time = "Time: " + node.Attributes["ows_CreateTime"].Value; String deadline = ""; String deadline1 = ""; if (node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"] != null) //未修改過的training按照end time計算deadline { DateTime a = Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value).AddDays(42); DateTime b= new DateTime(2015,3,31); if (Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value) < new DateTime(2015,4,1) && Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value) > new DateTime(2015, 3, 1)) { //判斷training是否是3月-4月的training a = b.AddDays(42); } deadline = "<b>before " + a.ToShortDateString().ToString() + @" </b>"; deadline1 = "before " + a.ToShortDateString().ToString() + @""; time = "From: <b>" + node.Attributes["ows_CreateTime"].Value + "</b> to: <b>" + node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value + "</b><Br /><Br />"; } if(node.Attributes["ows_Update_x0020_Date"] != null) //修改過的training按照修改日期計算deadline { if (Convert.ToDateTime(node.Attributes["ows_Update_x0020_Date"].Value) > Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value)) { DateTime a = Convert.ToDateTime(node.Attributes["ows_Update_x0020_Date"].Value).AddDays(21); //Console.WriteLine(a.ToShortDateString()); deadline = "<b>before " + a.ToShortDateString().ToString() + @" </b>"; deadline1 = "before " + a.ToShortDateString().ToString() + @""; } } //string ls_Subject = "" + (String)k2 + ", " + (String)k1 + @" Takes " + node.Attributes["ows_LinkTitle"].Value + @""; string ls_Subject = "" + node.Attributes["ows_LinkTitle"].Value + @"Training Follow-up Reminder: Required Completion Date "+ deadline1 +@""; SmtpMail.SmtpServer = "smtp-americas.hp.com"; MailMessage lo_Message = new MailMessage(); lo_Message.From = "[email protected]"; //lo_Message.To = node.Attributes["ows_Name"].Value.Substring(node.Attributes["ows_Name"].Value.IndexOf('#') + 1); lo_Message.Cc = "[email protected]"; lo_Message.Subject = ls_Subject; lo_Message.Priority = MailPriority.High; lo_Message.Body = @"<html> <body> <table border='0'> <tr> <font face='HP Simplified' size='小四'><td>Hello " + (String)name + @"</td></font> </tr> <tr> <td> </td> </tr> <tr> <font face='HP Simplified' size='小四'> <td>This is a kind reminder that you have not completed your training follow-up with your PM for <b>" + (int)day + @" days</b>.Please follow the link below and take actions " + deadline + @". </td> </font> </tr> <tr> <td> </td> </tr> <tr> <font face='HP Simplified' size='小四'> <td>Course Name: <b>" + node.Attributes["ows_LinkTitle"].Value + @"</b></td> </font> </tr> <tr><font face='HP Simplified' size='小四'><td>" + time + @"</td></font> </tr> <tr> <td><a href=" + @"http://ent261.sharepoint.hp.com/teams/jupiter_2/Lists/Training%20Record%20FY14/MyItems.aspx" + @"><font color='blue' face='HP Simplified' size='小四'>My Training Items</font></a></td> </tr> <tr> <font color='blue' face='HP Simplified' size='小四'>*Complete training follow-up in time is a mandatory action, according to Jupiter ground rules*</font> </tr> <br/><br/><br/><br/> </td> <font color='red' face='HP Simplified' size='小四'>FROM<br/>" + (String)fromName + @"</font> </td> <br/> </td> <font color='red' face='HP Simplified' size='小四'>TO<br/>" + (String)fromName + @"</font> </td> <br/> </td> <font color='red' face='HP Simplified' size='小四'>CC<br/>" + (String)ccName + @"</font> </td> </tr> </table> </body> </html>"; lo_Message.BodyEncoding = System.Text.Encoding.UTF8; lo_Message.BodyFormat = MailFormat.Html; SmtpMail.Send(lo_Message); } public static void SendE_Mail_Second(XmlNode node, Double day, String name, String ccName, String fromName) { string ls_Subject = "" + node.Attributes["ows_LinkTitle"].Value + @" Training Follow-up Final Notification"; String time = "Time: " + node.Attributes["ows_CreateTime"].Value; String deadline = ""; if (node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"] != null) //未修改過的training按照end time計算deadline { DateTime a = Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value).AddDays(42); DateTime b= new DateTime(2015,3,31); if (Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value)<=new DateTime(2015,3,31)) { a = b.AddDays(42); } deadline = "<b>before " + a.ToShortDateString().ToString() + @" </b>"; time = "From: <b>" + node.Attributes["ows_CreateTime"].Value + "</b> to: <b>" + node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value + "</b><Br /><Br />"; } if (node.Attributes["ows_Update_x0020_Date"] != null) //修改過的training按照修改日期計算deadline { if (Convert.ToDateTime(node.Attributes["ows_Update_x0020_Date"].Value) > Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value)) { DateTime a = Convert.ToDateTime(node.Attributes["ows_Update_x0020_Date"].Value).AddDays(21); //Console.WriteLine(a.ToShortDateString()); deadline = "<b>before " + a.ToShortDateString().ToString() + @" </b>"; } } SmtpMail.SmtpServer = "smtp-americas.hp.com"; MailMessage lo_Message = new MailMessage(); lo_Message.From = "[email protected]"; lo_Message.Cc = "[email protected]"; lo_Message.Subject = ls_Subject; lo_Message.Priority = MailPriority.High; lo_Message.Body = @"<html> <body> <table border='0'> <tr> <font face='HP Simplified' size='小四'><td>Hello " + (String)name + @"</td></font> </tr> <tr> <td> </td> </tr> <tr> <font face='HP Simplified' size='小四'> <td>This is a kind reminder that you have not completed your training follow-up action with your PM " + deadline + @".</td> </font> </tr> <tr> <td> </td> </tr> <tr> <font face='HP Simplified' size='小四'> <td>Course Name: <b>" + node.Attributes["ows_LinkTitle"].Value + @"</b></td> </font> </tr> <tr> <font face='HP Simplified' size='小四'> time " + time + @" </font> </tr> <tr> <td><a href=" + @"http://ent261.sharepoint.hp.com/teams/jupiter_2/Lists/Training%20Record%20FY14/MyItems.aspx" + @"><font color='blue' face='HP Simplified' size='小四'>My Training Items</font></a></td> </tr> <tr> <td> <font color='blue' face='HP Simplified' size='小四'>*Complete training follow-up in time is a mandatory action, according to Jupiter ground rules*</font> </td> <br/><br/><br/><br/> </td> <font color='red' face='HP Simplified' size='小四'>FROM<br/>" + (String)fromName + @"</font> </td> <br/> </td> <font color='red' face='HP Simplified' size='小四'>TO<br/>" + (String)fromName + @"</font> </td> <br/> </td> <font color='red' face='HP Simplified' size='小四'>CC<br/>" + (String)ccName + @"</font> </td> </tr> </table> </body> </html>"; lo_Message.BodyEncoding = System.Text.Encoding.UTF8; lo_Message.BodyFormat = MailFormat.Html; SmtpMail.Send(lo_Message); } protected override void OnStop() { string ls_Subject = "Training Course Reminding Service Shut Down"; SmtpMail.SmtpServer = "smtp-americas.hp.com"; MailMessage lo_Message = new MailMessage(); lo_Message.From = "[email protected]"; lo_Message.To = "[email protected]"; lo_Message.Cc = "[email protected]"; lo_Message.Subject = ls_Subject; lo_Message.Priority = MailPriority.High; lo_Message.Body = @"<html> <body> <table border='0'> <tr> <td>Hello,</td> </tr> <tr> <td> </td> </tr> <tr> <td>This is a kind reminder that the training course reminding service has been shut down;</td> </tr> <tr> <td> </td> </tr> <tr> <td>Please review with PM if need it restart</td> </tr> </table> </body> </html>"; lo_Message.BodyEncoding = System.Text.Encoding.UTF8; lo_Message.BodyFormat = MailFormat.Html; SmtpMail.Send(lo_Message); } */ public static void SendE_Mail(XmlNode node, Double day, String name, String ccName, String fromName) { String time = "Time: " + node.Attributes["ows_CreateTime"].Value; String deadline = ""; String deadline1 = ""; if (node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"] != null) //未修改過的training按照end time計算deadline { DateTime a = Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value).AddDays(42); DateTime b = new DateTime(2015, 3, 31); if (Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value) < new DateTime(2015, 4, 1) && Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value) > new DateTime(2015, 3, 1)) { //判斷training是否是3月-4月的training a = b.AddDays(42); } //deadline = "<b>before " + a.ToShortDateString().ToString() + @" </b>"; deadline = "<b>before " + a.Year.ToString() + @"-" + a.Month.ToString() + @"-" + a.Day.ToString() + @" </b>"; //deadline1 = "before " + a.ToShortDateString().ToString() + @""; deadline1 = "Before " + a.Year.ToString() + @"-" + a.Month.ToString() + @"-" + a.Day.ToString() + @""; time = "<font color='black' face='HP Simplified' size='小六'>·</font> From <b>" + @"<font style='font-weight:normal'>" + node.Attributes["ows_CreateTime"].Value + @"</font>" + @"</b> to <b>" + @"<font style='font-weight:normal'>" + node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value + @"</font>" + @"</b><Br />"; } if (node.Attributes["ows_Update_x0020_Date"] != null) //修改過的training按照修改日期計算deadline { if (Convert.ToDateTime(node.Attributes["ows_Update_x0020_Date"].Value) > Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value)) { DateTime a = Convert.ToDateTime(node.Attributes["ows_Update_x0020_Date"].Value).AddDays(21); //Console.WriteLine(a.ToShortDateString()); //deadline = "<b>before " + a.ToShortDateString().ToString() + @" </b>"; deadline = "<b>before " + a.Year.ToString() + @"-" + a.Month.ToString() + @"-" + a.Day.ToString() + @" </b>"; //deadline1 = "before " + a.ToShortDateString().ToString() + @""; deadline1 = "Before " + a.Year.ToString() + @"-" + a.Month.ToString() + @"-" + a.Day.ToString() + @""; } } string ls_Subject = "" + node.Attributes["ows_LinkTitle"].Value + @"Training Follow-up Reminder: Required Completion Date " + deadline1 + @""; MailMessage mailMsg = new MailMessage(); mailMsg.From = new MailAddress("[email protected]"); mailMsg.To.Add(fromName); mailMsg.CC.Add(ConfigurationSettings.AppSettings["PM"]); if (ccName != null) { mailMsg.CC.Add(ccName); } mailMsg.Subject = ls_Subject; mailMsg.BodyEncoding = Encoding.UTF8; mailMsg.IsBodyHtml = true; mailMsg.Priority = MailPriority.High; mailMsg.Body = @"<html> <body> <table border='0'> <tr> <font face='HP Simplified' size='小四'><td>Hello " + (String)name + @"</td></font> </tr> <tr> <td> </td> </tr> <tr> <font face='HP Simplified' size='小四'> <td>This is a kind reminder that you have not completed your training follow-up with your PM for <b>" + (int)day + @" days</b>. Please follow the link below and take actions " + deadline + @". </td> </font> </tr> <tr> <td> </td> </tr> <tr> <font face='HP Simplified' size='小四'> <td><font color='black' face='HP Simplified' size='小六'>·</font> Course Name: <b>" + @"<font style='font-weight:normal'>" + node.Attributes["ows_LinkTitle"].Value + @"</font>" + @"</b></td> </font> </tr> <tr><font face='HP Simplified' size='小四'><td>" + time + @"</td></font> </tr> <tr> <td><font color='black' face='HP Simplified' size='小六'>·</font> <a href=" + @"http://ent261.sharepoint.hp.com/teams/jupiter_2/Lists/Training%20Record%20FY14/MyItems.aspx" + @"><font color='#0096D6' face='HP Simplified' size='小四'>My Training Items</font></a></td> </tr> <tr> <font color='#0096D6' face='HP Simplified' size='小四'><Br /><i>*Complete training follow-up in time is a mandatory action, according to Jupiter ground rules*</i></font> </tr> </table> </body> </html>"; SmtpClient smtp = new SmtpClient(); smtp.Host = "smtp-americas.hp.com"; smtp.Send(mailMsg); } public static void SendE_Mail_Second(XmlNode node, Double day, String name, String ccName, String fromName) { string ls_Subject = "" + node.Attributes["ows_LinkTitle"].Value + @" Training Follow-up Final Notification"; String time = "Time: " + node.Attributes["ows_CreateTime"].Value; String deadline = ""; if (node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"] != null) //未修改過的training按照end time計算deadline { DateTime a = Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value).AddDays(42); DateTime b = new DateTime(2015, 3, 31); if (Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value) <= new DateTime(2015, 3, 31)) { a = b.AddDays(42); } //deadline = "<b>before " + a.ToShortDateString().ToString() + @" </b>"; deadline = "<b>before " + a.Year.ToString() + @"-" + a.Month.ToString() + @"-" + a.Day.ToString() + @" </b>"; time = "<font color='black' face='HP Simplified' size='小六'>·</font> From <b>" + @"<font style='font-weight:normal'>" + node.Attributes["ows_CreateTime"].Value + @"</font>" + @"</b> to <b>" + @"<font style='font-weight:normal'>" + node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value + @"</font>" + "</b><Br />"; //Console.WriteLine("deadline"+deadline); //Console.WriteLine("a"+a); //Console.WriteLine("a.ToString()"+a.ToString()); //Console.WriteLine("sucre style:" + a.Year+"-"+a.Month+"-"+a.Day); } if (node.Attributes["ows_Update_x0020_Date"] != null) //修改過的training按照修改日期計算deadline { if (Convert.ToDateTime(node.Attributes["ows_Update_x0020_Date"].Value) > Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value)) { DateTime a = Convert.ToDateTime(node.Attributes["ows_Update_x0020_Date"].Value).AddDays(21); //Console.WriteLine(a.ToShortDateString()); //deadline = "<b>before " + a.ToShortDateString().ToString() + @" </b>"; deadline = "<b>before " + a.Year.ToString() + @"-" + a.Month.ToString() + @"-" + a.Day.ToString() + @" </b>"; } } MailMessage mailMsg = new MailMessage(); mailMsg.From = new MailAddress("[email protected]"); mailMsg.To.Add(fromName); mailMsg.CC.Add(ConfigurationSettings.AppSettings["PM"]); if (ccName != null) { mailMsg.CC.Add(ccName); } mailMsg.Subject = ls_Subject; mailMsg.BodyEncoding = Encoding.UTF8; mailMsg.IsBodyHtml = true; mailMsg.Priority = MailPriority.High; mailMsg.Body = @"<html> <body> <table border='0'> <tr> <font face='HP Simplified' size='小四'><td>Hello " + (String)name + @"</td></font> </tr> <tr> <td> </td> </tr> <tr> <font face='HP Simplified' size='小四'> <td>This is a kind reminder that you have not completed your training follow-up action with your PM " + deadline + @".</td> </font> </tr> <tr> <td> </td> </tr> <tr> <font face='HP Simplified' size='小四'> <td><font color='black' face='HP Simplified' size='小六'>·</font> Course Name: <b>" + @"<font style='font-weight:normal'>" + node.Attributes["ows_LinkTitle"].Value + @"</font>" + @"</b></td> </font> </tr> <tr> <font face='HP Simplified' size='小四'><td>" + time + @"</td></font> </tr> <tr> <td><font color='black' face='HP Simplified' size='小六'>·</font> <a href=" + @"http://ent261.sharepoint.hp.com/teams/jupiter_2/Lists/Training%20Record%20FY14/MyItems.aspx" + @"><font color='#0096D6' face='HP Simplified' size='小四'>My Training Items</font></a></td> </tr> <tr> <td> <font color='#0096D6' face='HP Simplified' size='小四'><Br /><i>*Complete training follow-up in time is a mandatory action, according to Jupiter ground rules*</i></font> </td> </tr> </table> </body> </html>"; SmtpClient smtp = new SmtpClient(); smtp.Host = "smtp-americas.hp.com"; smtp.Send(mailMsg); } protected override void OnStop() { string ls_Subject = "Training Course Reminding Service Shut Down"; MailMessage mailMsg = new MailMessage(); mailMsg.From = new MailAddress("[email protected]"); mailMsg.To.Add("[email protected]"); mailMsg.CC.Add("[email protected]"); mailMsg.Subject = ls_Subject; mailMsg.Priority = MailPriority.High; mailMsg.Body = @"<html> <body> <table border='0'> <tr> <font color='black' face='HP Simplified' size='小四'> <td>Hello Zhao, Xu-Guang (Sucre, SSIT),</td> </font> </tr> <tr> <td> </td> </tr> <tr> <font color='red' face='HP Simplified' size='小四'> <td>This is a kind reminder that the training course reminding service has been shut down;</td> </font> </tr> <tr> <td> </td> </tr> <tr> <font color='black' face='HP Simplified' size='小四'> <td>Please review with PM if need it restart.</td> </font> </tr> </table> </body> </html>"; mailMsg.BodyEncoding = Encoding.UTF8; mailMsg.IsBodyHtml = true; SmtpClient smtp = new SmtpClient(); smtp.Host = "smtp-americas.hp.com"; smtp.Send(mailMsg); } public void timer1_Tick(object sender, EventArgs e) { KMService.Lists lists = new KMService.Lists(); lists.Url = "http://ent261.sharepoint.hp.com/teams/jupiter_2/_vti_bin/Lists.asmx"; lists.Credentials = CredentialCache.DefaultCredentials; XmlNode nodelistitems = null; // AllItem viewName = 728101AF-6727-430B-9220-35304FC7A3E5 nodelistitems = lists.GetListItems("8C851226-1615-44E0-B98E-08718E772D04", "728101AF-6727-430B-9220-35304FC7A3E5", null, null, "", null, null); //nodelistitems = lists.GetListItems("8C851226-1615-44E0-B98E-08718E772D04", null, null, null, "", null, null); XmlNode rsData = nodelistitems["rs:data"]; // ows_CreateTime = start time // ows_End_x0020_Time_x0020_of_x0020_Tr = end time foreach (XmlNode zRow in rsData.ChildNodes) { if (zRow.GetType().Name.ToString() != "XmlWhitespace") { if(zRow.Attributes["ows_CreateTime"]!=null){ if (Convert.ToDateTime(zRow.Attributes["ows_CreateTime"].Value) >= new DateTime(2015, 3, 1)) { //判斷Log training日期是否為3月1號之後 if (zRow.Attributes["ows_Follow_x002d_up_x0020_needed"] != null) { //Console.WriteLine(zRow.OuterXml); if ((zRow.Attributes["ows_Follow_x002d_up_x0020_needed"].Value == "Y" || zRow.Attributes["ows_Follow_x002d_up_x0020_needed"].Value == "Yes") && (zRow.Attributes["ows_Complete_x0020_following_x002d_u"].Value == "N" /*&& zRow.Attributes["ows_Name"].Value.Substring(zRow.Attributes["ows_Name"].Value.IndexOf('#') + 1) == "[email protected]"*/)) { //UTC時間 TimeSpan span = Convert.ToDateTime(zRow.Attributes["ows_CreateTime"].Value) - DateTime.UtcNow; if (zRow.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"] != null) { span = DateTime.Today - Convert.ToDateTime(zRow.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value); } DateTime Apr = new DateTime(2015,4,1);//4月1號????? if (Convert.ToDateTime(zRow.Attributes["ows_CreateTime"].Value) < Apr) //3月-4月的training統一按4月1號計算 { span = DateTime.Today - Apr; } if (zRow.Attributes["ows_Update_x0020_Date"] != null) //修改過狀態的training按照修改日期計算(如果修改時間在training完成時間之後) { //to do! end time? if (Convert.ToDateTime(zRow.Attributes["ows_Update_x0020_Date"].Value) > Convert.ToDateTime(zRow.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value)) { span = DateTime.Today - Convert.ToDateTime(zRow.Attributes["ows_Update_x0020_Date"].Value); } } String name = zRow.Attributes["ows_Name"].Value; //篩選 過濾到了郵箱名 String[] primaryEmail = name.Split('#'); String localName = primaryEmail[1]; String finalName = null; String ccName = null; String fromName = null; KMService.Lists namelists = new KMService.Lists(); namelists.Url = "http://ent261.sharepoint.hp.com/teams/jupiter_2/_vti_bin/Lists.asmx"; namelists.Credentials = CredentialCache.DefaultCredentials; XmlNode nodenamelistitemsF = null; //XmlNode nodenamelistitems = null; //7CBDCEBF-6850-4C02-826A-8BF6DA51D677 is Table "Team Member"; nodenamelistitemsF = namelists.GetListItems("7CBDCEBF-6850-4C02-826A-8BF6DA51D677", null, null, null, "", null, null); XmlNode rsnameDataF = nodenamelistitemsF["rs:data"]; foreach (XmlNode znameRow in rsnameDataF.ChildNodes) { if (znameRow.GetType().Name.ToString() != "XmlWhitespace") { if (znameRow.Attributes["ows_Title"] != null) { //Console.WriteLine(znameRow.Attributes["ows_Title"].Value); if (localName.Equals(znameRow.Attributes["ows_Title"].Value)) { finalName = znameRow.Attributes["ows_name1"].Value; fromName = localName; if (znameRow.Attributes["ows__x65b0__x5efa__x680f_1"] != null) { String cName = znameRow.Attributes["ows__x65b0__x5efa__x680f_1"].Value; String[] arrayname = cName.Split('#'); if (arrayname.Length == 2) { ccName = arrayname[1]; //Console.WriteLine(ccName); } } } } } } //對finalName進行篩選 過濾 if (finalName != null) { String[] primaryName = finalName.Split('#'); finalName = primaryName[1]; } // case for time period /* if ((int)span.TotalDays > 0 && (int)span.TotalDays <= int.Parse(ConfigurationSettings.AppSettings["first span"])) SendE_Mail(zRow, span.TotalDays + 1, finalName, ccName, fromName); if ((int)span.TotalDays >= int.Parse(ConfigurationSettings.AppSettings["first span"]) && (int)span.TotalDays <= int.Parse(ConfigurationSettings.AppSettings["second span"])) SendE_Mail_Second(zRow, span.TotalDays + 1, finalName, ccName, fromName); */ //case for time dot if ((int)span.TotalDays > 0 &&(int)span.TotalDays == int.Parse(ConfigurationSettings.AppSettings["first span"])) SendE_Mail(zRow, span.TotalDays + 1, finalName, ccName, fromName); if ((int)span.TotalDays >= int.Parse(ConfigurationSettings.AppSettings["first span"])&&(int)span.TotalDays == int.Parse(ConfigurationSettings.AppSettings["second span"])) SendE_Mail_Second(zRow, span.TotalDays + 1, finalName, ccName, fromName); } } } } } } // OnStop(); } } }
關於代碼,做幾點說明:重寫的onStop()函數,僅僅是在程序員手動去停掉一個服務的時候,才會觸發這個onStop()函數,雖然部署在服務器上的程序健壯性不錯,但是如果因為某些意外情況的發生,miss掉該發而沒有發的郵件的話,那換句話就是說,該收到reminder的人,沒有收到reminder。那麼這也就失去了寫這個程序的本意。在大公司動不動就要寫郵件,就是防止miss掉一些事情,秋後算賬的時候好有prove.再附上App.config代碼
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <section name="SharePointWorklow.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </sectionGroup> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> </startup> <appSettings> <add key="INTERVAL" value="86400000" /> <add key="first span" value="20" /> <add key="second span" value="41" /> <add key="PM" value="[email protected]"/> <add key="ClientSettingsProvider.ServiceUri" value="" /> </appSettings> <system.web> <membership defaultProvider="ClientAuthenticationMembershipProvider"> <providers> <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" /> </providers> </membership> <roleManager defaultProvider="ClientRoleProvider" enabled="true"> <providers> <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" /> </providers> </roleManager> </system.web> </configuration>
在這個裡面配置了一些系統級的變量,如把PM的郵箱映射到了字符串PM,這樣在項目後期的維護當中,其實提供了一種更為便捷的操作方法。再附Program.cs代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.ServiceProcess; using System.Text; namespace SharePointWorklow { static class Program { /// <summary> /// The main entry point for the application. /// </summary> static void Main() { if (true) { Service1 service = new Service1(); service.Debug(null); } else { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new Service1() }; ServiceBase.Run(ServicesToRun); } } } }
如果要把項目發布成一個windows服務的時候,需要在main函數中注釋掉if中的部分,注釋後如下:
using System; using System.Collections.Generic; using System.Linq; using System.ServiceProcess; using System.Text; namespace SharePointWorklow { static class Program { /// <summary> /// The main entry point for the application. /// </summary> static void Main() { /* if (true) { Service1 service = new Service1(); service.Debug(null); } else { */ ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new Service1() }; ServiceBase.Run(ServicesToRun); // } } } }
接下來要說一下發布項目,我們要在sharepointWorkflow/bin/Debug下,寫一個文件Install.bat。這樣當雙擊它的時候,就會發布成一個window服務,Install.bat裡面的內容如下:
%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\InstallUtil /i SharePointWorklow.exe pause
這裡有個需要注意的地方,將來部署到服務器中後,需要把符號'\'切換為‘/’(雖然是要部署在windows服務器上),如果不這樣操作的話,由於路徑的不對,發布為service會被access denied掉,然後,將項目發布成了windows服務,還有一個需要注意的地方是,在view designer的時候,裡面的server name必須要與你service1的名字相一致,這樣,程序發布成服務之後,才有可能正確的找到你內部的函數來執行。
補充一些知識點:
1.文件終結符:EOF;end of file.
2.路徑分隔符,在windows下是\,在Linux下是/.
3.行分隔符在windows 下是 \r\n,在Linux下面是 \n, 在Mac下是 \r.
4.在windows中發布項目的時候,切忌配置文件中的路徑不能用空格,對於復雜名字的盡量使用駝峰法則命名法,否則這些細節也會導致部署項目的時候Install失敗的。
備注幾點:路徑分隔符引起的問題,就像在eclipse中的編碼引起的問題一樣,這樣的細節處,也會導致項目編譯的失敗。所以在項目出錯的情況下,去檢查問題的時候,這些點處也應該pay little attention去處理。
項目的後期准備,解決一下標記發送郵件的狀態,並且如果郵件服務器downtime掉的話,如果Bcc到一個人,或者是一群PDL的話,可以減少程序的風險級別。如果項目後期有什麼技術層面上的大的改動,繼續更新此博客。
大家有不會的問題,可以相互交流,謝謝!!!