namrata's profileNashaPhotosBlogListsMore Tools Help

Blog


    December 23

    Windows Services Part - 5 ( StartUp Parameters & Service Controller )

    Hi Group,

    This is continuation to Windows Service. I was requested to discuss how to send startup Parameters and start and stop a windows service programmatically.

    Let us first see how we can send startup parameters to our MoveFile windows service and even control the service programmatically. When we created this windows service we had hard coded the windows service parameters We will now pass the target folder and the destination folder as startup parameters.

    For this we will have to make some changes in the existing code.

    In MoveFile.cs we will have to add two variables for storing the target and destination folder as follows: -

    public class MoveFile

    {

    Thread currThread;

    string targetFolderPath = null;

    string destinationFolderPath = null;

    public MoveFile(string targetFolder,string destinationFolder)

    {

    targetFolderPath= targetFolder;

    destinationFolderPath = destinationFolder;

    currThread = new Thread(new ThreadStart(StartMoving));

    currThread.Start();

    }

    We now need to modify the constructor of the MoveFIle Class to take values of these two parameters as shown above.

    If you take a look at the OnStart function of MoveFilesService you will notice that the function takes an array of strings as an input parameter. We will modify the implementation of this function to check whether parameters are passed or not. If parameters are not passed then we set a default value to them.

    protected override void OnStart(string[] args)

    {

    if(args.GetLength(0) != 2)

    {

    args = new string[2];

    args[0] = @"E:\FilesToMove";

    args[1] = @"E:\MovedFiles";

    }

    oMoveFile = new MoveFile(args[0],args[1]);

    }

     

     

    To control the service we will need a service controller. . NET Framework provides us with a service controller class. So let us prepare our service controller.

    Open a new windows application. Add a form to it and add four buttons and one label to the form.

    We will use the label to display the current service status and the four buttons to start, stop, pause and resume our win service.

    Add reference to System.ServiceProcess at the top as follows:

    using System.ServiceProcess;

    Create an object of the service controller at the class level

    private System.ServiceProcess.ServiceController sc;

    Go to the design of your Form and add check out the properties of your service controller.

    One of the properties is ServiceName. Select the Service Name as your MoveFilesService.

    ServiceController provides you with methods to control your service. So will call these methods in the each of these button click events.

    Rename the buttons as Start,Stop,Pause and Resume.

    Currently I m passing the parameters hard coded from my service controller program you can even pick them from app config file.

    This is code that we need to put into the click event of each of these buttons: -

    private void Start_Click(object sender, System.EventArgs e)

    {

    if(sc.Status == ServiceControllerStatus.Stopped)

    {

    sc.Start(new string[]{"E:\\MovedFiles","E:\\FilesToMove"});

    label2.Text = "Service Started";

    }

    }

    private void Stop_Click(object sender, System.EventArgs e)

    {

    sc.Stop();

    label2.Text = "Service Stopped";

    }

    private void Pause_Click(object sender, System.EventArgs e)

    {

    if(sc.Status == ServiceControllerStatus.Running)

    {

    sc.Pause();

    label2.Text = "Service Paused";

    }

    }

    private void Resume_Click(object sender, System.EventArgs e)

    {

    if(sc.Status == ServiceControllerStatus.Paused)

    {

    sc.Continue();

    label2.Text = "Service Resumed";

    }

    }

    Run the application and check out the functionality.

    If you explore other functions of Service Controller (static functions) you will find that it provides you with functions to enlist services, device services etc.

    e.g. ServiceController.GetServices

    ServiceController.GetDevices

    December 12

    Windows Services Part - 4

    In the past 3 days we have created our windows service, added installers to it, Created event logged our service today we will add  performance counters.

    Performance counter helps us to monitor performance of our service. Say if want to know how many files are moved, what is the number of files moved per second /minute etc.

    Before we add performance counter we will add NoOfFiles property to our MoveFile class.

                    private long noOfFiles=0;
                    public long NoOfFiles
                    {
                            get
                            {
                                    return noOfFiles;
                            }
                    }


    To add performance counter to our windows service : <o:p></o:p>

    • Go to Server Explorer<o:p></o:p>
    • Go to Servers<o:p></o:p>
    • Under that you will see your machine name <o:p></o:p>
    • Expand the node under that you will see performance counters.<o:p></o:p>
    • Right click that and select create new category<o:p></o:p>
    • Performance counter builder dialog will open up.<o:p></o:p>
    • Add the category name say "MoveFilesService" or your service name<o:p></o:p>
    • Add the description    <o:p></o:p>
    • Click on New<o:p></o:p>
    • Add the counter name ... "NoOfFilesMoved"<o:p></o:p>
    • Type should be NumberOfItems32<o:p></o:p>
    • Enter the description …  "NoofFilesMoved"<o:p></o:p>
    • And Click on Ok.<o:p></o:p>


    Check the tree view on your left your Performance counter category (MoveFilesService) and its counter (NoOfFilesMoved) should be created.

    Drag and drop the NoOfFilesMoved Performance counter from the tree view on MoveFileService (design mode). Performancecounter1 will be created rename it as PCNoOfFiles .. Check out its properties.

    After adding the performance counter we will add a timer to our service that will help us to refresh PCNoOfFiles value after every second.

    Drag and Drop a timer control on MoveFileService from the components tab in your toolbox.

    Double click on timer control it should go to its _Elaspsed event. We will assign the value of NoOfFiles to our performance counters rawvalue.

                    private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
                    {
                            PCNoOfFiles.RawValue = oMoveFile.NoOfFiles;
                    }

    Build your project. Install the service … start your service ... go to Administrative Tools ... Performance.

    Select System Monitor on your system performance monitor.  Click on the Add toolbar button on your right to open.  Add Counters dailog box.

    Select MoveFilesService in the Performance Object select box and Click on Add.

    You will see a red bar moving and displaying you the no of files moved. Check out the last, average, minimum, maximum and duration parameters.

    Note: To view good graphs add some files in your FileToMove Folder and then view the performance.

    Windows Services Part - 3

    After creating our windows service today we will see how we can add event logging to it.

    You can view all the existing event logs with event viewer (control panel -> administrative tools -> event viewer ).

    You will basically fined 3 types of logs application, system and security.

    To add EventLogging to our service.

    Go to design mode of your windows service ... from components drag and drop eventlog name it as moveFileEventlog

    Set the auto log property of your service to false (We had set this to true initially refer part 1)

    Set the log and source properties of your log to Application and MoveFiles as below

                            this.moveFileEventLog.Log = "Application";
                            this.moveFileEventLog.Source = "MoveFiles";                    

    Go to all the events of your service like Onstart,OnPause,OnStop and OnContinue and add a message line as shown below.

                    protected override void OnStart(string[] args)
                    {
                            oMoveFile = new MoveFile();
                            moveFileEventLog.WriteEntry("MoveFiles Service Started",EventLogEntryType.Information);
                    }
                    protected override void OnPause()
                    {
                            moveFileEventLog.WriteEntry("MoveFiles Service Paused",EventLogEntryType.Information);
                            oMoveFile.PauseMoving();
                    }
                    protected override void OnStop()
                    {
                            moveFileEventLog.WriteEntry("MoveFiles Service Stopped",EventLogEntryType.Information);
                            oMoveFile.StopMoving();                
                    }

                    protected override void OnContinue()
                    {
                            moveFileEventLog.WriteEntry("MoveFiles Service Resumed",EventLogEntryType.Information);
                            oMoveFile.ResumeMoving();
                    }


    Now go back to the design mode of your service to add installer for your log.

    Select your event log... Check out its properties.... Below its properties there is an add installer link.

    This will add an eventloginstaller in your project installer class.

    Build uninstall the older version if installed and then reinstall your service.

    Check out the application log in the even viewer will find the start message.

    Try to pause and resume the service; its corresponding event log messages will be registered.

    Windows Services Part - 2

    Yesterday we created our MoveFiles Windows Service. Today we will add installers to our windows service, install our service and then go ahead and debug our service.

    To add installers to our service we need to go to Design mode of our MoveFileService.cs and then click on properties.

    You will see that there is a link called Add Installer at the bottom of the properties window. Click on that link

    Notice that a new class called as ProjectInstaller.cs should be added to your project. Go to the design mode of your ProjectInstaller class and checkout serviceProcessInstaller1 and serviceInstaller1 objects added to it.

    ServiceProcessInstaller1 is an object of ServiceProcessInstaller and ServiceInstaller1 is an object of ServiceInstaller.

    Checkout the properties of both esp. serviceInstaller1. Amongst all the property present, one of the properties is StartType which is set to Manual by default i.e. this service will have to be started manually. You can even set it to automatic or disabled. If you set it to automatic then your service will start as soon as the OS starts.

    Let us now checkout our Installers in some more detail.

    ProjectInstaller : This is our main Installer class. If you check out it is inherited from System.Configuration.Install.Installer the base class of all the Installer classes i.e. if you have to create your own custom installer it should be inherited from this class.
    The installer base class has Install, commit,rollback and uninstall methods. You can override these methods if you want to do any sp. task but do not forget to call the baseclass method in your new overriding method.

    Another thing that you need to take into account is the RunInstaller attribute at the top of the ProjectInstaller class. This attribute tells that whenever this assembly is to be installed ProjectInstaller should be involved. Hence if you are creating your custom installer than you should put this attribute at the top of your installer class for it to be invoked.

    ServiceProcessInstaller :- This class installs executables which are derived from the ServiceBase class. One instance of this class is required per service application. This class has properties of service process and all the properties of the various services in that process. Mind you one service process can contain more that one services.

    ServiceInstaller :- For each service in the service process one service installer is need. Since we have only one service we will require only one. If you add one more service to your project you will require another service installer class to install that service.


    Let us now checkout the InitializeComponent function of ProjectInstaller class.

                    private void InitializeComponent()
                    {
                            this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
                            this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
                            //
                            // serviceProcessInstaller1
                            //
                            this.serviceProcessInstaller1.Password = null;
                            this.serviceProcessInstaller1.Username = null;


    Here is a part of it. Checkout the first two lines. It is this Intitalize component which creates these installers within the ProjectInstaller class. After that you will notice the user name and password for this serviceprocess. By default they are set to null if you set them to any specific value then that username password will be used to install and run the service. If you leave it null (which is the default) then when you are installing this service you will be prompted for username and password using the ServiceInstallerDailog.

    So now after we have added our installer class let us build our service.

    One of the Tools that I had not covered in my .NET Tools Series is Installutil. The reason behind it being that I wanted to cover it with windows services by creating a windows service and using it as an example.

    Go to VS.Net command prompt ... type installutil /? and checkout its properties.

    To install our assembly we will have to go to our assembly folder on the command prompt and then type the following command.

            installutil <Name of your assembly>.exe

    Note : If your assembly is not installed . or the installation process in rollbacked get back to me . I will help you out.
              To uninstall your assembly use installutil /u <Name of your assembly>.exe

    After installing the service now we will debug our service.

    Debugging a windows service is different from any other normal application. Since this runs as an external process you will have to attach the process to your service application.

    Open your service application keep a break point on OnStart method of your MoveFilesService.

    Now start your service by going to Control Panel , Adminsitrative Tools , Services . Select your service, right click and select start.

    Immediately attach the process to your service application by going to Debug -> Processes -> Check Show system processes -> Select your windows service.  Click on Attach -> Click Ok -> Click on Close.

    Note: It might take some time for the process to come to your break point. So please bea little patient.

    There you are debugging your windows service.

    Have a gr8 time doin it ..... ENJOY !!!!!

    Windows Services Part - 1

    Windows services are applications that start as soon as the OS starts although they can be configured to start manually.

    To view all the windows services available on your machine you can go to Start -> Settings-> Control Panel -> Admistrative Tools -> Services. A windows service can run under a specific user or under the system user.

    Generally all those applications that do not require any human intervention are preferred as windows service, say a background job.

    Today the service that we will create will move the files from one location to another location.

    Open a windows service application let the Service1.cs remain as it is now. We will come back to it a little later. Add a new class and name it MoveFile.cs

    So let us start by creating a simple class called MoveFile. Add the following references to MoveFile

    using System;
    using System.Threading;
    using System.IO;

    In this class we will create we will declare a private thread. This thread will initiate the file movement from one folder to another.

    public class MoveFile
    {
    Thread currThread;
    public MoveFile()
    {
    currThread = new Thread(new ThreadStart(StartMoving));
    currThread.Start();
    }
    }

    In the constructor of the class we create a new thread by setting its thread start and start the thread. As soon as our thread will be started StartMoving will be called. So Let us check out its implementation

    public void StartMoving()
    {
    while(1==1)
    {
    string[] files = Directory.GetFiles(@"E:\FilesToMove");
    for(int i=0;i<files.GetUpperBound(0);i++)
    {
    File.Move(files[i],@"E:\MovedFiles" +files[i].Substring(files[i].LastIndexOf("\\")));
    Console.WriteLine(files[i]);
    }
    }
    }

    Note : For the sake of simplicity and demo purpose the paths have been hardcoded. You can add an application config file and read the paths from there.

    Here I am having two folders FilesToMove and MovedFiles in my E: I am having a while loop which continuously checks for files in my

    FilestoMove folder and if there are any files in it I am moving them to MovedFiles.

    Since a windows service can be stopped, paused, resumed and abort we want our service to also exhibit the same behavior.
    So let us add functions to MoveFile for the same.

    public void PauseMoving()
    {
    currThread.Suspend();
    }

    public void StopMoving()
    {
    currThread.Abort();
    }

    public void ResumeMoving()
    {
    currThread.Resume();
    }


    Thus we have created our MoveFile Class that moves files from FileToMove to MovedFiles Folder.

    This class is a generic class, you can also use it with a normal windows or console application. But we will create a windows service using it.

    All the classes, which are required for creating a windows service, are present in System.ServiceProcess Namespace.

    Any service that we create has to inherit from ServiceBase class. This class is used to register the service and handle its events.

    Coming back to Service1.cs rename it to MoveFilesService. Please see to it that you change the name in solution explorer as well as the class constructor.

    In InitailizeCompoment function there is a statement which talks about the service name ( as shown below) please make the changes there also.

    this.ServiceName = "MoveFilesService";

    In the Main function of your service class checkout Services added to your ServicesToRun Array change it to MoveFilesService

    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new MoveFilesService() };

    Check out the name in properties of your MoveFilesService class. Compile your project , it should not give you any errors.

    Go to the properties of MoveFile and set

    AutoLog = true
    CanPauseAndContinue = true
    CanStop = true

    Add a private variable of MoveFile to MoveFileService class.

    public class MoveFilesService : System.ServiceProcess.ServiceBase
    {
    MoveFile oMoveFile;


    We will now add code to OnStart method of our Service Class where we will instantiate an object of MoveFile.

    protected override void OnStart(string[] args)
    {
    oMoveFile = new MoveFile();
    }

    ServiceBase class has got methods to Pause, Stop and Resume a service. We will have to override them and provide an implementation to pause, stop and resume our service as follows.

    protected override void OnPause()
    {
    oMoveFile.PauseMoving();

    }
    protected override void OnStop()
    {
    oMoveFile.StopMoving();
    }

    protected override void OnContinue()
    {
    oMoveFile.ResumeMoving();

    }

    The methods that we had made in our MoveFile class are called here. Hence whenever our windows service is paused our thread will also exhibit the same behavior.

    Compile the project and see that you don't get any errors will see how to install our windows service tomorrow.