Definition: Microsoft Windows services enable you to create long-running executable applications that run in their own Windows sessions. These services (e.g. SQL server Service) can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface. Whenever you need long-running functionality that does not interfere with other users who are working on the same computer.
We can start, stop, or pause a Windows service from the Windows Services management console. This MMC (Microsoft Management Console) can be opened by selecting the group from the Administrative Tools programs group. All the services currently running on our system.
Windows Services in DOTNET
To make a Windows service, we need three types of operational programs. They are as follows:
• Service Program
• Service Control Program
• Service Configuration program
Service Program
A Service Program is the main program where our code resides. Here, we write the actual logic for our service. One point to note here is that each service program can refer to more than one service but each one of these services must contain their own entry point or a Main() method. This Main() method is just like the Main() method in C#.
To write a service class, we need to inherit it from a ServiceBase class. The ServiceBase class is a part of the System.ServiceProcess class.
Service Control Program
A service control program is a part of the operating system. It is responsible for the starting, stopping, and pausing of a Windows service. To implement a Windows service, we need to inherit from the ServiceController class of the System.ServiceProcess class.
Service Configuration Program
Once a service is made, it needs to be installed and configured. Configuration involves that this service will be started manually or at boot time. To implement a service program, we need to inherit from the ServiceProcessInstaller class of ServiceInstaller.
To create a new Windows service, select a Windows service project. Type a project name and click OK. VS.NET will create the basic code for us. We will just have to write the logic of the code.
There is one important thing to consider in the Main() method:
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
namespace MonitoringService
{
static class Program
{
///
/// The main entry point for the application.
///
static void Main()
{
ServiceBase[] ServicesToRun = new ServiceBase[]
{
new MonitoringWinService()
};
ServiceBase.Run(ServicesToRun);
}
}
}
MonitoringService.config
MonitoringWinService.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.Configuration;
using System.IO;
namespace MonitoringService
{
public partial class MonitoringWinService : ServiceBase
{
readonly EventLog eventLog1 = new EventLog();
readonly System.Timers.Timer timer1 = new System.Timers.Timer();
public MonitoringWinService()
{
InitializeComponent();
timer1.Enabled = true;
timer1.Start();
timer1.Interval= 60000; // One Minute
if(!System.Diagnostics.EventLog.SourceExists("MonitoringWinService"))
System.Diagnostics.EventLog.CreateEventSource("MonitoringWinService",
"MonitoringWinService_Logging");
eventLog1.Source = "MonitoringWinService";
eventLog1.Log = "MonitoringWinService_Logging";
}
#region Properties
private string _MonitoringFolder = string.Empty;
public string MonitoringFolder
{
set
{
if(!string.IsNullOrEmpty(ConfigurationSettings.AppSettings["FolderPath"].ToString()))
{
_MonitoringFolder = mCheckFolderPath(ConfigurationSettings.AppSettings["FolderPath"].ToString());
}
else
{
_MonitoringFolder = @"c:\Image_Folder\"; // Default Value
}
}
get
{
return _MonitoringFolder;
}
}
private string _LogFile = string.Empty;
public string LogFile
{
set
{
if(!string.IsNullOrEmpty(ConfigurationSettings.AppSettings["WinService_log"].ToString()))
{
_LogFile = ConfigurationSettings.AppSettings["WinService_log"].ToString();
}
else
{
_LogFile = @"C:\MonitoringService_LogFile.log"; // Default Value
}
}
get
{
return _LogFile;
}
}
#endregion
#region CustomMethods
///
/// For Monitoring Folder Size
///
///
///
public int mGetDirectoryLength(string strDirectory)
{
long iTotalSize = 0;
List
try
{
foreach (string d in Directory.GetFiles(strDirectory))
{
iTotalSize = iTotalSize + mGetFileLength(d);
}
return mConvertBytesIntoGB(iTotalSize);
}
catch (System.Exception excpt)
{
return 0;
}
}
///
/// Convert Bytes into MB
///
///
///
public int mConvertBytesIntoMB(long bytes)
{
return Convert.ToInt32(Math.Round(bytes / 1024.0 / 1024.0, 2));
}
///
/// Convert Bytes into GB
///
///
///
public int mConvertBytesIntoGB(long bytes)
{
return Convert.ToInt32(Math.Round(bytes / 1024.0 / 1024.0 / 1024.0, 2));
}
///
/// Get File Length of the File
///
///
///
public long mGetFileLength(string strFilePath)
{
if (!string.IsNullOrEmpty(strFilePath))
{
FileInfo info = new System.IO.FileInfo(strFilePath);
return info.Length;
}
return 0;
}
///
/// To Check the Folder Path.
/// Adding slash at end to make it valid path
///
///
///
public static string mCheckFolderPath(string strpath)
{
if(!string.IsNullOrEmpty(strpath))
{
if(strpath.Substring((strpath.Length-1), 1)!=@"\")
{
return strpath.Insert(strpath.Length, @"\");
}
return strpath;
}
return strpath;
}
///
/// Log-Writer
///
///
public void mWriteLogFile(string LogMessage)
{
if (LogMessage == null) throw new ArgumentNullException("LogMessage");
if (!File.Exists(LogFile))
File.Create(LogFile);
FileStream fs = new FileStream(LogFile, FileMode.Open, FileAccess.Write);
StreamWriter writer = new StreamWriter(fs, ASCIIEncoding.Default);
writer.WriteLine(LogMessage);
writer.Flush();
writer.Close();
fs.Close();
}
#endregion
protected override void OnStart(string[] args)
{
mWriteLogFile("Service Started ............." + DateTime.Now);
eventLog1.WriteEntry("Service Started " + DateTime.Now);
}
protected override void OnStop()
{
mWriteLogFile("Service Stopped ............." + DateTime.Now);
eventLog1.WriteEntry("Service Stopped " + DateTime.Now);
}
protected override void OnContinue()
{
mWriteLogFile("Image_Folder monitoring in Process " + DateTime.Now);
eventLog1.WriteEntry("Image_Folder monitoring in Process " + DateTime.Now);
}
private void timer1_Tick(object sender, EventArgs e)
{
mWriteLogFile(string.Format("Folder Size [GB] {0} - DateTime {1}", mGetDirectoryLength(MonitoringFolder).ToString(), DateTime.Now.ToString()));
eventLog1.WriteEntry(string.Format("Folder Size [GB]{0} - DateTime {1}", mGetDirectoryLength(MonitoringFolder).ToString(), DateTime.Now.ToString()));
}
}
}
InstallerClass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ServiceProcess;
namespace MonitoringService
{
[RunInstallerAttribute(true)]
public class InstallerClass : System.Configuration.Install.Installer
{
public InstallerClass()
{
ServiceInstaller si = new ServiceInstaller();
ServiceProcessInstaller spi = new ServiceProcessInstaller();
si.ServiceName = "MonitoringImageFolder";
si.DisplayName = "MonitoringImageFolder";
si.StartType = ServiceStartMode.Automatic;
this.Installers.Add(si);
spi.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
spi.Username=null;
spi.Password=null;
this.Installers.Add(spi);
}
}
}
Deployment Process
To add a deployment project
1. On the File menu, point to Add, and then click New Project.
2. In the Add New Project dialog box's Project Type pane, open the Other Project Types node, select Setup and Deployment Projects. In the Templates pane, choose Setup Project. In the Name box, type MonitoringService_Setup.
The project is added to Solution Explorer and the File System Editor is displayed.
3. In the File System Editor, select Application Folder in the left pane. On the Action menu, point to Add, and then choose Project Output.
4. In the Add Project Output Group dialog box, OpenWeb3 will be displayed in the Project list. Select Primary Output.
Primary Output from OpenWeb (Active) appears in the Application Folder.
To add the custom action
1. Select the MonitoringService_Setup project in Solution Explorer. On the View menu, point to Editor, and then choose Custom Actions.
The Custom Actions Editor is displayed.
2. In the Custom Actions Editor, select the Commit node. On the Action menu, choose Add Custom Action.
3. In the Select Item in Project dialog box, double-click the Application Folder. Then select Primary output from MonitoringService.
Primary output from MonitoringService appears under the Commit node in the Custom Actions Editor.
4. In the Properties window, make sure that the InstallerClass property is set to True (this is the default).
5. In the Custom Actions Editor, select the Install node and add Primary output from MonitoringService to this node as you did for the Commit node.
6. On the Build menu, choose MonitoringService_Setup.
InstallUtil could also be use to Install the Windows Service
Open a Visual Studio .NET Command Prompt
Change to the bin\Debug directory of your project location (bin\Release if you compiled in release mode)
Issue the command InstallUtil.exe MonitoringService.exe to register the service and have it create the appropriate registry entries
Open the Computer Management console by right clicking on My Computer on the desktop and selecting Manage
In the Services section underneath Services and Applications you should now see your Windows Service included in the list of services
Start your service by right clicking on it and selecting Start
Each time you need to change your Windows Service it will require you to uninstall and reinstall the service. Prior to uninstalling the service it is a good idea to make sure you have the Services management console closed. If you do not you may have difficulty uninstalling and reinstalling the Windows Service. To uninstall the service simply reissue the same InstallUtil command used to register the service and add the /u command switch