Windows Services 实战指南 II

本文将跟踪一天中的小时数。如果时间与配置文件中指定的小时相匹配,它将读取数据库。如果有匹配的日期,它将发送电子邮件。

在本文中,可以找到许多编码细节,例如从配置文件中读取数据、从数据库中读取数据、使用计时器控件以及以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; }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485