先说一下这个项目做了什么。先介绍一下背景(备注一下,每次项目发生更改之后,要进行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 = "no-reply@hp.com";
//lo_Message.To = node.Attributes["ows_Name"].Value.Substring(node.Attributes["ows_Name"].Value.IndexOf('#') + 1);
lo_Message.Cc = "xu-guang.zhao@hp.com";
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>&nbsp;</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>&nbsp;</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 = "no-reply@hp.com";
lo_Message.Cc = "xu-guang.zhao@hp.com";
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>&nbsp;</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>&nbsp;</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 = "no-reply@hp.com";
lo_Message.To = "xu-guang.zhao@hp.com";
lo_Message.Cc = "xu-guang.zhao@hp.com";
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>&nbsp;</td>
</tr>
<tr>
<td>This is a kind reminder that the training course reminding service has been shut down;</td>
</tr>
<tr>
<td>&nbsp;</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();
DateTime b = new DateTime(, , );
if (Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value) < new DateTime(, , ) && Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value) > new DateTime(, , ))
{ //判断training是否是3月-4月的training
a = b.AddDays();
}
//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>&nbsp;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();
//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("no-reply@hp.com");
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>&nbsp;</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>&nbsp;</td>
</tr>
<tr>
<font face='HP Simplified' size='小四'> <td><font color='black' face='HP Simplified' size='小六'>·</font>&nbsp;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>&nbsp;<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();
DateTime b = new DateTime(, , );
if (Convert.ToDateTime(node.Attributes["ows_End_x0020_Time_x0020_of_x0020_Tr"].Value) <= new DateTime(, , ))
{
a = b.AddDays();
}
//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>&nbsp;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();
//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("no-reply@hp.com");
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>&nbsp;</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>&nbsp;</td>
</tr>
<tr>
<font face='HP Simplified' size='小四'>
<td><font color='black' face='HP Simplified' size='小六'>·</font>&nbsp;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>&nbsp;<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("no-reply@hp.com");
mailMsg.To.Add("xu-guang.zhao@hp.com");
mailMsg.CC.Add("xu-guang.zhao@hp.com");
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>&nbsp;</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>&nbsp;</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(, , ))
{
//判断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) == "yubo.bai@hp.com"*/))
{ //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(,,);//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[]; 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 == )
{
ccName = arrayname[];
//Console.WriteLine(ccName);
}
}
}
}
}
}
//对finalName进行筛选 过滤
if (finalName != null)
{
String[] primaryName = finalName.Split('#');
finalName = primaryName[];
} // 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 > &&(int)span.TotalDays == int.Parse(ConfigurationSettings.AppSettings["first span"])) SendE_Mail(zRow, span.TotalDays + , 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 + , 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="" />
<add key="first span" value="" />
<add key="second span" value="" />
<add key="PM" value="jie.sheng@hp.com"/>
<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="" />
</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的话,可以减少程序的风险级别。如果项目后期有什么技术层面上的大的改动,继续更新此博客。

大家有不会的问题,可以相互交流,谢谢!!!

C#实现WebService服务 项目完整总结的更多相关文章

  1. 二十、【.Net开源】EFW框架核心类库之WebService服务

    回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.1:http://pan.baidu.com/s/1qWJjo3U EFW框架实例源代码下载:http://pan.baid ...

  2. JAVA项目中公布WebService服务——简单实例

    1.在Java项目中公布一个WebService服务: 怎样公布? --JDK1.6中JAX-WS规范定义了怎样公布一个WebService服务. (1)用jdk1.6.0_21以后的版本号公布. ( ...

  3. 如何在SpringMVC项目中部署WebService服务并打包生成客户端

    场景 某SpringMVC项目原本为一个HTTP的WEB服务项目,之后想在该项目中添加WebService支持,使该项目同时提供HTTP服务和WebService服务.其中WebService服务通过 ...

  4. day63-webservice 08.在web项目中配置带有接口的webservice服务

    这个是配置带有接口的WebService的服务. http://localhost:8080/cxf-web-server/service 带有接口的实现类也给它做好了.jaxws:endpoint是 ...

  5. Spring整合CXF之发布WebService服务

    今天我们来讲下如何用Spring来整合CXF,来发布WebService服务: 给下官方文档地址:http://cxf.apache.org/docs/writing-a-service-with-s ...

  6. JAX-WS 学习一:基于java的最简单的WebService服务

    JAVA 1.6 之后,自带的JAX-WS API,这使得我们可以很方便的开发一个基于Java的WebService服务. 基于JAVA的WebService 服务 1.创建服务端WebService ...

  7. 【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

    不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务:另外还可以使用Ajax调用WebService服务. 预备工作:开启WebService服务,使用jd ...

  8. WebService学习总结(四)——调用第三方提供的webService服务

    http://www.cnblogs.com/xdp-gacl/p/4260627.html 互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他 ...

  9. Java创建WebService服务及客户端实现(转)

    简介 WebService是一种服务的提供方式,通过WebService,不同应用间相互间调用变的很方便,网络上有很多常用的WebService服务,如:http://developer.51cto. ...

随机推荐

  1. rabbitmq消息队列——"发布订阅"

    三."发布订阅" 上一节的练习中我们创建了一个工作队列.队列中的每条消息都会被发送至一个工作进程.这节,我们将做些完全不同的事情--我们将发送单个消息发送至多个消费者.这种模式就是 ...

  2. fir.im Weekly - 2016 年 Android 最佳实践列表

    2016 年已经过去一半,你在年初制定的成长计划都实现了吗? 学海无涯,技术成长不是一簇而就的事情.本期 fir.im Weekly 推荐 王下邀月熊_Chevalier的 我的编程之路--知识管理与 ...

  3. 快速入门系列--WCF--07传输安全、授权与审核

    这部分主要涉及企业级应用的安全问题,一般来说安全框架主要提供3个典型的安全行为:认证.授权和审核.除了典型的安全问题,对于一个以消息作为通信手段的分布式应用,还需要考虑消息保护(Message Pro ...

  4. 【资源】C++学习资料 - 逆天整理 - 精华无密版【最新】

    再失效就太无语了,链接都是多份的~~—————————————————基础——————————————C++环境搭建(全套)http://pan.baidu.com/s/1o6y0smY链接:http ...

  5. hdu4751Divide Groups(dfs枚举完全图集合或者bfs染色)

    /************************************************************************* > File Name: j.cpp > ...

  6. SharePoint Server 2013开发之旅(二):使用在线的开发人员网站进行SharePoint App开发

    上一篇我已经介绍了新版本的SharePoint Server提供了四种主要的开发场景,其中一个全新的App开发模型让我们眼前一亮.这一篇我将介绍如何在线进行SharePoint App开发. 谈到Sh ...

  7. 简单的小工具wordlight——让VS变量高亮起来

    前段时间一直在使用matlab,今天需要使用vs2008,而用惯了matlab,习惯了其中一项选中变量高亮的设置,突然回来使用VS,感到各种不适应,顿时想到了一个词:矫情 呵呵,于是在网上找各种插件, ...

  8. Windows Azure Web Site (15) 取消Azure Web Site默认的IIS ARR

    <Windows Azure Platform 系列文章目录> 我们知道,Azure Web Site (改名为Azure Web App)默认是可以保留Session的.Azure We ...

  9. Windows Azure Service Bus (4) Service Bus Queue和Storage Queue的区别

    <Windows Azure Platform 系列文章目录> 熟悉笔者文章的读者都了解,Azure提供两种不同方式的Queue消息队列: 1.Azure Storage Queue 具体 ...

  10. app令牌的一个token实现

    app登陆验证不能使用session来判断了.然后查资料都说用令牌,没找到合适的方法,我的眼界太小.另外,越来越感觉基础的重要,比如,session是什么,我竟无言以对.不知道session是什么,怎 ...