Create Windows Service and Send Mail Daily At Fixed Time Using C#

Introduction

In this article I am explaining how to create a Windows Service to schedule daily mail at a specified time. Scheduling email and sending the email is a basic requirement of any project.

Step 1

Open Visual Studio and create a new project. Under Windows Desktop select Windows Service and provide a proper name and click on the OK button.

window service

Step 2

Rename the service1 class to a proper name. In this case I am using mail service. Click on “Click here to switch to code view”.

mail service

Step 3

Add some app settings in the app.config file as in the following:

  1. <appSettings>  
  2.    <add key="StartTime" value="08:33 PM "/>  
  3.    <add key="callDuration" value="2"/>  
  4.    <add key="CallType" value="1"/>  
  5.    <add key="FromMail" value="****"/>  
  6.    <add key="Password" value="****"/>  
  7.    <add key="Host" value="smtpout.secureserver.net"/>  
  8. </appSettings>  
Step 4

In the MailService class write the following function.
  1. public Scheduler()  
  2. {  
  3.    InitializeComponent();  
  4.    int strTime = Convert.ToInt32(ConfigurationManager.AppSettings["callDuration"]);  
  5.    getCallType = Convert.ToInt32(ConfigurationManager.AppSettings["CallType"]);  
  6.    if (getCallType == 1)  
  7.    {  
  8.       timer1 = new System.Timers.Timer();  
  9.       double inter = (double)GetNextInterval();  
  10.       timer1.Interval = inter;  
  11.       timer1.Elapsed += new ElapsedEventHandler(ServiceTimer_Tick);  
  12.    }  
  13.    else  
  14.    {  
  15.       timer1 = new System.Timers.Timer();  
  16.       timer1.Interval = strTime * 1000;  
  17.       timer1.Elapsed += new ElapsedEventHandler(ServiceTimer_Tick);  
  18.    }  
  19. }  
Note: For using the ConfigurationManager add the reference first and then use the class. 
  1. private double GetNextInterval()  
  2. {  
  3.    timeString = ConfigurationManager.AppSettings["StartTime"];  
  4.    DateTime t = DateTime.Parse(timeString);  
  5.    TimeSpan ts = new TimeSpan();  
  6.    int x;  
  7.    ts = t - System.DateTime.Now;  
  8.    if (ts.TotalMilliseconds < 0)  
  9.    {  
  10.       ts = t.AddDays(1) - System.DateTime.Now;//Here you can increase the timer interval based on your requirments.   
  11.    }  
  12.    return ts.TotalMilliseconds;  
  13. }  
  14. private void SetTimer()  
  15. {  
  16.    try  
  17.    {  
  18.       double inter = (double)GetNextInterval();  
  19.       timer1.Interval = inter;  
  20.       timer1.Start();  
  21.    }  
  22.    catch (Exception ex)  
  23.    {  
  24.    }  
  25. }  
In the timer OnStart() function first write a message to the log that the service has been started and when the service stops write to the log that the service has stopped.
  1. protected override void OnStart(string[] args)  
  2. {  
  3.     timer1.AutoReset = true;  
  4.     timer1.Enabled = true;  
  5.     ServiceLog.WriteErrorLog("Daily Reporting service started");  
  6. }  
  7.  
  8. protected override void OnStop()  
  9. {  
  10.     timer1.AutoReset = false;  
  11.     timer1.Enabled = false;  
  12.     ServiceLog.WriteErrorLog("Daily Reporting service stopped");  
  13. }  
Here I am creating a class ServiceLog that contains the followings function. 
  1. /// <summary>  
  2. /// This function write log to LogFile.text when some error occurs.  
  3. /// </summary>  
  4. /// <param name="ex"></param>  
  5. public static void WriteErrorLog(Exception ex)  
  6. {  
  7.     StreamWriter sw = null;  
  8.     try  
  9.     {  
  10.         sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\LogFile.txt"true);  
  11.         sw.WriteLine(DateTime.Now.ToString() + ": " + ex.Source.ToString().Trim() + "; " + ex.Message.ToString().Trim());  
  12.         sw.Flush();  
  13.         sw.Close();  
  14.     }  
  15.     catch  
  16.     {  
  17.     }  
  18. }  
  19. /// <summary>  
  20. /// this function write Message to log file.  
  21. /// </summary>  
  22. /// <param name="Message"></param>  
  23. public static void WriteErrorLog(string Message)  
  24. {  
  25.     StreamWriter sw = null;  
  26.     try  
  27.     {  
  28.         sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\LogFile.txt"true);  
  29.         sw.WriteLine(DateTime.Now.ToString() + ": " + Message);  
  30.         sw.Flush();  
  31.         sw.Close();  
  32.     }  
  33.     catch  
  34.     {  
  35.     }  
  36. }  
This class also contains a function that will send email to the mail id passed by its arguments. 
  1. #region Send Email Code Function  
  2.      /// <summary>  
  3.      /// Send Email with cc bcc with given subject and message.  
  4.      /// </summary>  
  5.      /// <param name="ToEmail"></param>  
  6.      /// <param name="cc"></param>  
  7.      /// <param name="bcc"></param>  
  8.      /// <param name="Subj"></param>  
  9.      /// <param name="Message"></param>  
  10.      public static void SendEmail(String ToEmail, string cc, string bcc, String Subj, string Message)  
  11.      {  
  12.          //Reading sender Email credential from web.config file  
  13.   
  14.          string HostAdd = ConfigurationManager.AppSettings["Host"].ToString();  
  15.          string FromEmailid = ConfigurationManager.AppSettings["FromMail"].ToString();  
  16.          string Pass = ConfigurationManager.AppSettings["Password"].ToString();  
  17.   
  18.          //creating the object of MailMessage  
  19.          MailMessage mailMessage = new MailMessage();  
  20.          mailMessage.From = new MailAddress(FromEmailid); //From Email Id  
  21.          mailMessage.Subject = Subj; //Subject of Email  
  22.          mailMessage.Body = Message; //body or message of Email  
  23.          mailMessage.IsBodyHtml = true;  
  24.   
  25.          string[] ToMuliId = ToEmail.Split(',');  
  26.          foreach (string ToEMailId in ToMuliId)  
  27.          {  
  28.              mailMessage.To.Add(new MailAddress(ToEMailId)); //adding multiple TO Email Id  
  29.          }  
  30.   
  31.   
  32.          string[] CCId = cc.Split(',');  
  33.   
  34.          foreach (string CCEmail in CCId)  
  35.          {  
  36.              mailMessage.CC.Add(new MailAddress(CCEmail)); //Adding Multiple CC email Id  
  37.          }  
  38.   
  39.          string[] bccid = bcc.Split(',');  
  40.   
  41.          foreach (string bccEmailId in bccid)  
  42.          {  
  43.              mailMessage.Bcc.Add(new MailAddress(bccEmailId)); //Adding Multiple BCC email Id  
  44.          }  
  45.          SmtpClient smtp = new SmtpClient();  // creating object of smptpclient  
  46.          smtp.Host = HostAdd;              //host of emailaddress for example smtp.gmail.com etc  
  47.   
  48.          //network and security related credentials  
  49.   
  50.          smtp.EnableSsl = false;  
  51.          NetworkCredential NetworkCred = new NetworkCredential();  
  52.          NetworkCred.UserName = mailMessage.From.Address;  
  53.          NetworkCred.Password = Pass;  
  54.          smtp.UseDefaultCredentials = true;  
  55.          smtp.Credentials = NetworkCred;  
  56.          smtp.Port = 3535;  
  57.          smtp.Send(mailMessage); //sending Email  
  58.      }  
  59.  
  60.      #endregion   
Step 5

Now inside the MailService class write a ServiceTimer_Tick() function. This function is mainly used for the task done by this Window Service when the timer tic reaches the time specified in the app.config file. You can change your code based on your requirements.
  1. private void ServiceTimer_Tick(object sender, System.Timers.ElapsedEventArgs e)  
  2. {  
  3.     string Msg = "Hi ! This is DailyMailSchedulerService mail.";//whatever msg u want to send write here.  
  4.     // Here you can write the   
  5.     ServiceLog.SendEmail("manishki007@gmail.com""abc@live.com""manishki@live.com""Daily Report of DailyMailSchedulerService on " + DateTime.Now.ToString("dd-MMM-yyyy"), Msg);  
  6.   
  7.     if (getCallType == 1)  
  8.     {  
  9.         timer1.Stop();  
  10.         System.Threading.Thread.Sleep(1000000);  
  11.         SetTimer();  
  12.     }  
  13. }  
Step 6

Now your Windows Service is ready. Compile this and use the following procedure to install and use this Windows Service.

Install Windows Service. 
  1. Go to "Start" >> "All Programs" >> "Microsoft Visual Studio 2012" >> "Visual Studio Tools" . Click "Developer Command Prompt for VS2012".

    Type the following command:

    cd <physical location of your DailyMailSchedulerService.exe file>

    In my case it is:

    cd D:\Dot Net Program\DailyMailSchedulerService\DailyMailSchedulerService\bin\Debug

  2. Type the following command:

    InstallUtil.exe “DailyMailSchedulerService.exe”

    And press Enter.

    Now go to Services and find the services of your project name and start that service. You will then start finding the mail every day at 08:00 PM.
Debug Window Service
  1. Build the Solution.
  2. Start your Service.
  3. While your Service is starting, go to --> Debug --> Attach Process.
  4. Make sure "Show Process from all users" and "Show Process in all sessions" are checked.
  5. Find your "" in the list and click "Attach".
  6. You should now be at the breakpoint you inserted.

Summary

In this illustration we learned about Windows Service and sending mail daily by using that service. This may be helpful somehow when scheduling something based on your requirements. Please provide your valuable comments about this article.

X

Build smarter apps with Machine Learning, Bots, Cognitive Services - Start free.

Start Learning Now