本文将跟踪一天中的小时数。如果时间与配置文件中指定的小时相匹配,它将读取数据库。如果有匹配的日期,它将发送电子邮件。
在本文中,可以找到许多编码细节,例如从配置文件中读取数据、从数据库中读取数据、使用计时器控件以及以HTML格式发送电子邮件。
拥有事件日志对于跟踪服务非常有用。因此,首先,让创建一个。(如果想让生活更轻松,可以下载前一篇文章中的代码。那里已经有一个事件日志控件。)
它可以从工具箱拖放到SimpleService.cs(设计模式)。添加代码以创建一个事件日志控件及其详细信息。之后,将拥有以下代码块:
public SimpleService() {
InitializeComponent();
// Initialize eventLogSimple
if (!System.Diagnostics.EventLog.SourceExists("SimpleSource"))
System.Diagnostics.EventLog.CreateEventSource("SimpleSource", "SimpleLog");
// SimpleSource will appear as a column in eventviewer.
eventLogSimple.Source = "SimpleSource";
// SimpleLog will appear as an event folder.
eventLogSimple.Log = "SimpleLog";
}
由于没有常规的用户界面,可以使用配置文件通过配置文件传递任何参数。因此,可以通过在Visual Studio 2005的解决方案资源管理器中右键单击项目,然后点击添加、新建项和应用程序配置文件,然后点击确定,简单地添加一个配置文件。之后,将在项目部分看到app.config文件。双击打开它,并在
这意味着服务将在10:00读取数据并发送电子邮件。(假设时间设置基于0-24小时。)
让以简单的方式完成这项工作。首先,必须添加System.Configuration库,添加以下行:
using System.Configuration;
然后让创建一个从配置文件中读取数据的函数。该函数如下所示:
private string ReadConfigFile() {
// Create an AppSettingReader object.
System.Configuration.AppSettingsReader appsreader = new AppSettingsReader();
string value = String.Empty;
// Get the value Hour from config file.
value = (String)appsreader.GetValue("Hour", value.GetType());
// Return it.
return value.ToString();
}
可以使用名为bd.mdb的Access表,并使用.NET Framework的OldeDb提供程序。因此,必须在SimpleService.cs的顶部添加using System.Data.OleDb;。还必须创建连接字符串,并在while循环中查询并发送邮件给当天出生的人。发送邮件是通过另一个函数实现的,稍后将进行解释。以下是代码块:
private bool ReadDataFromDB() {
string sPName = "";
string sPSurname = "";
string sPEmail = "";
// What are the day and month today?
string strMonth = DateTime.Now.Month.ToString();
string strDay = DateTime.Now.Day.ToString();
// string strAppPath = System.IO.Directory.GetCurrentDirectory();
// Create query string which selects Last names,
// Names and Emails if the day and month match.
string sQuery = "Select * from BirthDays where Days='" + strDay + "' and Months='" + strMonth + "';";
string sConnString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\bd.mdb";
// Write the stage and the brand new query string to the log.
eventLogSimple.WriteEntry("ReadDataFromDB() called...");
eventLogSimple.WriteEntry(sQuery);
// Create DB objects.
// Assuming that bd.mdb found on c: driver root : c:\bd.mdb
OleDbConnection DBConn = new OleDbConnection(sConnString);
OleDbCommand DBComm = new OleDbCommand(sQuery);
DBComm.CommandType = CommandType.Text;
DBComm.Connection = DBConn;
// let's do DB jobs in a try.
try {
eventLogSimple.WriteEntry("In try...");
DBConn.Open();
OleDbDataReader DBReader = DBComm.ExecuteReader();
while (DBReader.Read()) {
// Write the stage to the log.
eventLogSimple.WriteEntry("In while...");
sPName = DBReader.GetValue(2).ToString();
sPSurname = DBReader.GetValue(1).ToString();
sPEmail = DBReader.GetValue(5).ToString();
SendMailToStaff(sPEmail, sPName + " " + sPSurname);
SendMailToWebAdmin("admin@company.com", "Birthday service sent e-mail to: " + sPName + " " + sPSurname);
// Write the job done to the log.
eventLogSimple.WriteEntry("E-mail: " + DBReader.GetValue(5).ToString() + "- Staff Name: " + sPName + " " + sPSurname);
}
} catch {
// Write if there is an error to the log.
eventLogSimple.WriteEntry("An error has occurred!");
} finally {
// Close connection
DBConn.Close();
}
return true;
}
现在需要一个计时器来决定何时采取行动:
private System.Timers.Timer mytimer = null;
然后,必须在OnStart中创建一个计时器对象。它将如下所示:
protected override void OnStart(string[] args) {
// Write "started.." to the log file.
eventLogSimple.WriteEntry("Simple service started!");
// Get time to send from config file.
sTimeToSend = ReadConfigFile();
// Write "time to send" to the log file.
eventLogSimple.WriteEntry("Time to send: " + sTimeToSend);
// Create timer object and set timer tick to an hour
MyTimer = new System.Timers.Timer(3600000);
MyTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.ServiceTimer_Tick);
MyTimer.Enabled = true;
}
然后,让创建一个Tick事件:
private void ServiceTimer_Tick(object sender, System.Timers.ElapsedEventArgs e) {
MyTimer.Enabled = false;
string sCurrentHour = DateTime.Now.Hour.ToString() + ":00";
DateTime dCurrentHour = Convert.ToDateTime(sCurrentHour);
DateTime dTimeToSend = Convert.ToDateTime(sTimeToSend);
int iComparison = DateTime.Compare(dTimeToSend, dCurrentHour);
if (iComparison == 0)
ReadDataFromDB();
MyTimer.Enabled = true;
}
要发送邮件,将使用System.Net.Mail库,因此必须再次添加到顶部:
using System.Net.Mail;
服务将向Web管理员发送一封通知邮件。
private bool SendMailToWebAdmin(string sTo, string sText) {
SmtpClient SClient = new SmtpClient();
System.Net.Mail.MailMessage msgMail = new System.Net.Mail.MailMessage();
// Most probably the SClient.Host will vary for you.
// So you must write your own.
SClient.Host = "10.1.1.28";
SClient.Port = 25;
MailAddress strFrom = new MailAddress("xyx@xyzmail.com");
string strTo = sTo;
string strSubject = "Corporate Portal Service - Birthday Congratulation - (Monitoring) ";
string strEmailBody = sText;
msgMail.Body = strEmailBody;
msgMail.Subject = strSubject;
msgMail.To.Add(strTo);
msgMail.From = strFrom;
msgMail.IsBodyHtml = true;
if (strTo.Trim() != "") {
try {
SClient.Send(msgMail);
eventLogSimple.WriteEntry("Sent");
return true;
} catch {
eventLogSimple.WriteEntry("Failed");
return false;
}
}
return false;
}
发送给人们的邮件是通过另一个发送HTML内容的函数实现的。不幸的是,不能在这里放置HTML。通常会发送一个非常丰富多彩的页面。
private bool SendMailToStaff(string sTo, string sName) {
SmtpClient SClient = new SmtpClient();
System.Net.Mail.MailMessage msgMail = new System.Net.Mail.MailMessage();
// Most probably the SClient.Host will vary for you.
// So you must write your own.
SClient.Host = "10.1.1.28";
SClient.Port = 25;
MailAddress strFrom = new MailAddress("xyx@xyzmail.com");
string strTo = sTo;
string strSubject = "Happy Birthday " + sName + "!";
string strEmailBody = @"HTML STRING COMES HERE";
msgMail.Body = strEmailBody;
msgMail.Subject = strSubject;
msgMail.To.Add(strTo);
msgMail.From = strFrom;
msgMail.IsBodyHtml = true;
if (strTo.Trim() != "") {
try {
SClient.Send(msgMail);
eventLogSimple.WriteEntry("Sent");
return true;
} catch {
eventLogSimple.WriteEntry("Failed");
return false;
}
}
return false;
}