In this article I will explain with a simple example how to automatically send emails daily at specific time using Windows Service in C# and VB.Net.
The Windows Service will run daily at the specified time and will automatically trigger a method to fetch records from database and send email to all records.
Concept
In this article the Windows Service will execute a Task daily at a specific time. The Task is to fetch all records of Students who have a Birthday today.
Such students will receive an email containing Birthday wishes automatically by the Windows Service.
Database
I have made use of the following table Students with the schema as follows.
I have already inserted few records in the table.
Note: You can download the database table SQL by clicking the download link below.
Building the Windows Service
I have already explained how to build a Windows Service to execute a task at a specific time on daily basis in my article
The same code will be used with little additions for sending emails daily.
App.Config Modifications
In the App.Config file, you need to set the Mode to Daily and the ScheduledTime to the time on which the Windows Service to execute the Task.
You also need to specify the Connection String the database in the App.Config ConnectionStrings section.
<appSettings>
<add key ="Mode" value ="Daily" />
<add key ="IntervalMinutes" value ="1" />
<add key ="ScheduledTime" value ="17:43" />
</appSettings>
<connectionStrings>
<add name="constr" connectionString="Data Source=.\SQL2008R2;Initial Catalog=StudentsDB;integrated security=true" />
</connectionStrings>
Modifying the SchedularCallback event handler
We will need to modify the SchedularCallback event handler in order to automatically fetch records of Students who have a Birthday and send them emails.
First a query is executed to fetch all Student records by matching the Day and Month of their Birthdate with the Day and Month of the Current Date respectively.
Then a loop is executed and one by one an email is sent to each Student.
Once the Task is accomplished the Windows Service enters resting mode and will again perform the same task after 24 hours at the specified time.
Note: I am using Gmail Mail settings for this example, but you can use settings of any Mail Server of your choice.
C#
private void SchedularCallback(object e)
{
try
{
DataTable dt = new DataTable();
string query = "SELECT Name, Email FROM Students WHERE DATEPART(DAY, BirthDate) = @Day AND DATEPART(MONTH, BirthDate) = @Month";
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("@Day", DateTime.Today.Day);
cmd.Parameters.AddWithValue("@Month", DateTime.Today.Month);
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
}
}
}
foreach(DataRow row in dt.Rows)
{
string name = row["Name"].ToString();
string email = row["Email"].ToString();
WriteToFile("Trying to send email to: " + name + " " + email);
using (MailMessage mm = new MailMessage("sender@gmail.com", email))
{
mm.Subject = "Birthday Greetings";
mm.Body = string.Format("<b>Happy Birthday </b>{0}<br /><br />Many happy returns of the day.", name);
mm.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.EnableSsl = true;
System.Net.NetworkCredential credentials = new System.Net.NetworkCredential();
credentials.UserName = "sender@gmail.com";
credentials.Password = "<Password>";
smtp.UseDefaultCredentials = true;
smtp.Credentials = credentials;
smtp.Port = 587;
smtp.Send(mm);
WriteToFile("Email sent successfully to: " + name + " " + email);
}
}
this.ScheduleService();
}
catch (Exception ex)
{
WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);
//Stop the Windows Service.
using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SimpleService"))
{
serviceController.Stop();
}
}
}
VB.Net
Private Sub SchedularCallback(e As Object)
Try
Dim dt As New DataTable()
Dim query As String = "SELECT Name, Email FROM Students WHERE DATEPART(DAY, BirthDate) = @Day AND DATEPART(MONTH, BirthDate) = @Month"
Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand(query)
cmd.Connection = con
cmd.Parameters.AddWithValue("@Day", DateTime.Today.Day)
cmd.Parameters.AddWithValue("@Month", DateTime.Today.Month)
Using sda As New SqlDataAdapter(cmd)
sda.Fill(dt)
End Using
End Using
End Using
For Each row As DataRow In dt.Rows
Dim name As String = row("Name").ToString()
Dim email As String = row("Email").ToString()
WriteToFile("Trying to send email to: " & name & " " & email)
Using mm As New MailMessage("sender@gmail.com", email)
mm.Subject = "Birthday Greetings"
mm.Body = String.Format("<b>Happy Birthday </b>{0}<br /><br />Many happy returns of the day.", name)
mm.IsBodyHtml = True
Dim smtp As New SmtpClient()
smtp.Host = "smtp.gmail.com"
smtp.EnableSsl = True
Dim credentials As New System.Net.NetworkCredential()
credentials.UserName = "sender@gmail.com"
credentials.Password = "<Password>"
smtp.UseDefaultCredentials = True
smtp.Credentials = credentials
smtp.Port = 587
smtp.Send(mm)
WriteToFile("Email sent successfully to: " & name & " " & email)
End Using
Next
Me.ScheduleService()
Catch ex As Exception
WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace)
'Stop the Windows Service.
Using serviceController As New System.ServiceProcess.ServiceController("SimpleService")
serviceController.[Stop]()
End Using
End Try
End Sub
Screenshot
Email sent to the Student
Downloads