Windows Services in C#: Adding the Installer (part 3)

OK, you’ve crafted your service, now you’re ready to install it so you can test. To do so you’ll need to create an installer for your project. However, you don’t create an installer in the traditional fashion.

Instead, switch to the “TimeLoggerService.cs [Design]” tab. Now in that big gray area right click, and pick “Add Installer”.

[Picture of Add Installer Menu]

Visual Studio will do some magic and you’ll have a new ProjectInstaller.cs added to your project. It also added a few new references to the solution. If the “ProjectInstaller.cs [Design]” tab is not up, bring it up, and click on the serviceInstaller1 item.

Let’s start by giving it a decent name, I chose ArcaneTimeLoggerServiceInstaller. Now for the Description property I entered “The Arcane Code Time Logging Service”. For DisplayName I gave it “Arcane Code Time Logger”. Finally, I’m leaving the StartType property to Manual, you may wish to alter this for your “real world” service.

Now go back and click on the serviceProcessInstaller1. We’ll change it’s name to ArcaneTimeLoggerServiceProcessInstaller. If you remember the discussion from part 1, you will recall a discussion about the security. Here in the Account property is where you will want to set that. Since all this sample does is a minimal amount of logging, I can go with a fairly low level of security and set to “LocalSystem”.

OK, we’re almost done. Right click the project name (in my case TimeLogger) and select properties from the menu. (Note, make sure to click the project, not the solution!) Now on the Application tab, under “Startup object” pick TimeLogger.Program. Now save everything and build your project.

Assuming your build was successful, you can now install and test your windows service. There are two ways to install, we can use the installutil.exe, or create a full blown MSI installer. Since we are just at the point of debugging, we will use the simple installutil.exe.

To preset all the pathing you’ll need for install util, we’ll need to open a Visual Studio Command Window. Start, All Programs, Microsoft Visual Studio 2005, Visual Studio Tools, Visual Studio Command Window. If you are running under Vista, STOP! Do NOT click on Visual Studio Command Window. Instead, right click and pick “Run as Administrator”. Again that’s for Vista, for XP just click since you likely have Admin rights.

The moral is without Admin rights InstallUtil fails every time, and it drove me up the wall trying to figure this out.

Now in the command window navigate to the bin\debug folder where your project compiled. Type in installutil TimeLogger.exe (or whatever you named your exe).

[Picture of Command Prompt]

If everything goes well, you s hould get the messages “The Commit phase completed successfully” and “The transacted install has completed”. Now let’s go see if we were successful.

Open the Microsoft Management Console (Start, Run, MMC)). When it opens, pick the Services and EventViewer snap-ins. Under Services, you should easily find the ArcaneTimeLogger, just double click on it and start it. Once it starts you can close the dialog.

Now head over to the Event Viewer. Click on the “Create Custom View”, to make it easy to find our log events. In the “Create Custom View” dialog, select “By source” and in the drop down check the ones for ArcaneTimeLogging. Click OK to close.

[Picture of Create Custom View]

Your view should now update to look something like this:

[Picture of MMC with our Events]

Congratulations, you’ve now coded and installed a basic windows service, and more over logged events from your service. This sample app we just created can serve as a basic template for all of your future windows services.

By the way, we should probably not get carried away with the euporia. Let’s take a moment and clean up. Return to the services area of the MMC and double click on our ArcaneTimeLogger. Now Stop the service, so it won’t be continually logging the time.

Now that it’s not running, let’s uninstall it. Return to the Visual Studio Command Window and simply type the command “installutil /u TimeLogger.exe”. The /u switch will tell InstallUtil to uninstall our service named TimeLogger.exe. And with that you’ve take care of your clean up work. Tomorrow we’ll talk a bit about debugging a windows service.

24 Responses to “Windows Services in C#: Adding the Installer (part 3)”

  1. tittatty Says:

    I kept getting an error “The source ‘Service1′ is not registered in log ‘Service1Log’. (It is registered in log ‘Application’.) ” The Source and Log properties must be matched, or you may set Log to the empty string, and it will automatically be matched to the Source property.” When i tried to run this service so i had to do this when creating the event log:

    EventLog evt = new EventLog(”Application”, System.Environment.MachineName, “Service1″);

  2. Silvio L. Says:

    I tried the example above and it ran… but the log entries I could see were the start / stop service log entries. I attached the debugger and I can see the handler for the Elapsed event being called, and no uncaught exceptions are reported by the debugger. The EventLog.WriteEntry() function does not return an error code, so I cannot figure out why this does not work.

    Any ideas?

  3. Silvio L. Says:

    Figured it out. EventLog.WriteEntry() fails if there are spaces in the source string. A bit strange that no exception is thrown when such a failure occurs–makes it a little tricky to debug as the service just keeps moving along despite the failure to log the entry.

  4. manasi bopardikar Says:

    I did not see the service in the MMC

  5. Mark Hubers Says:

    You can use the pre and post build options to manage loading and unloading service. Ex,
    PRE-BUILD:
    net stop “ServiceName”
    %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /u “ServiceName”
    POST-BUILD:
    %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /i “ServiceName”
    net start “ServiceName”

    You can go one step farther if you name your service the same as the project name. Ex.
    PRE-BUILD:
    net stop “$(TargetName)”
    %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /u “$(TargetName)”
    POST-BUILD:
    %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /i “$(TargetName)”
    net start “$(TargetName)”

  6. Yuriy Says:

    To make last code work should add “.exe”
    EX:
    net stop “$(TargetName)”
    %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /u “$(TargetName)”.exe
    %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /i “$(TargetName)”.exe
    net start “$(TargetName)”

  7. sami Says:

    Hi all,
    Has anyone already tried calling statich methods within the windows service?? it seems that i’m facing some problems with this…
    Sorry if’t not the appropriate page to post this question.
    Regards.

  8. Pavan Says:

    Is “Create Custom View” for Event Logger only available in Vista. I could not find it XP.

  9. Mr me Says:

    hi, I tried the obove example, but when I tried to install it using installutill, I get the message:
    ‘istallutil’ is not recognized as internal or external command, operable program or batch file
    I’m using a computer in a network, i asked the network administrator to put me as administrator because it is required as i read obove, he said i’m already administrator.

    can someone help me why i get this message, althought I am administrator?

  10. Mr me Says:

    hi, i found the solution and i wan to share it
    for the command window to recognize installutill.exe, i have to put the whole path:
    for VS 2005:
    C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\InstallUtil.exe C:\MyService.exe

    for VS 2003:
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe C:\MyService.exe
    ofcourse there is space between the installutil path and the win service paht, but if you’re already in the folder of the win service you don’t have to write its path

  11. Nguyen Trong Thanh Says:

    Dear arcanecode,

    I have a problem with my windows services is: Right now, i using the Local System account for my service, the service have to download and save the files to a remote PC. but the services can’t save the files to the remote PC because it is missing permission. i have received a message in event log “logon fail, bad usernam or password”… so, how to pass this problem? any solution for me?

  12. oblade Says:

    Hey Mr me. I think you wanted to say this:

    for VS 2003:
    C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\InstallUtil.exe C:\MyService.exe

    for VS 2005:
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe C:\MyService.exe

  13. Hanno Says:

    Hi. I just about going nuts here. I’ve created my service, added the ProjectInstaller, set all the properties, Added the Installation Project, added my service as the project output, and deployed. The setup program runs fine, the project is created on the specified location, BUT THE SERVICE IS NOT CREATED!!! What am I missing?

  14. webequipped Says:

    I too have the same problem as Hanno. I am using VS2008. I have triple checked everything and still cannot get the service to install on my W2K3 server. My build platform is Vista. Can anyone shed some light?

  15. Tom V Says:

    Just to throw my hat in the ring, I am having the same problem with Vista and VS2008… I am using a setup project and when I install nothing shows anywhere …not the services control app nor the log except to say that it was installed. I hope someone can shed some light.

  16. Otis Says:

    I am having issue as Tom V and Hanno, working in Vista

    • Stewart Simpson Says:

      Hi Otis,
      You have to add a custom action in your MSI project.
      So in custom actions, add the output of your service to the Install section. This will then run the required installation code for your service. i.e. the same as what the installutil.exe does
      Hope that helps
      Stewart

  17. Stephen Henry Says:

    It worked absolutely fine at the first go itself :-) Thanks a lot

  18. Irfan Cehajic Says:

    To repeat Warrick Wilson’s comment here, as I encountered the same problem he had (his comment was on day 2 page).

    “I’m using VS 2008 and couldn’t get the timer event to log anything. After a little Googling and trying a few things, I got the following to work:

    protected void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
    string sSource = “ArcaneTimeLogger”;
    string sLog = “Application”;

    if (!EventLog.SourceExists(sSource))
    EventLog.CreateEventSource(sSource, sLog);

    EventLog evt = new EventLog();
    string message = “Arcane Time:”
    + DateTime.Now.ToShortDateString() + ” ”
    + DateTime.Now.ToShortTimeString();
    evt.Source = “ArcaneTimeLogger”;
    evt.WriteEntry(message, EventLogEntryType.Information);
    }

  19. anto Says:

    hi…i want to ask something…
    im using vs2008…
    why my windows service suddenly stopped without information in the viewer log???
    and its appear vs2008 debuger option.

    is there someone can help me???
    thanx…

  20. noam Says:

    just want to say thanks

  21. Sane Pete Says:

    Problem:
    System.ComponentModel.Win32Exception: No mapping between account names and security IDs was done

    Solution:
    Go to InitializeComponent() in ProjectInstaller.cs
    Right Click and choose ‘Go To Definition’.
    Add this to the InitializeComponent() function:

    this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;

    It all works lovely.

  22. Paresh Says:

    Hi, thanks for sharing this.
    I am having one problem. I am using VB 2005 Express Edition and in that I don’t have “Add Installer” Option in the menu so how do add installer Programmatically??

    Please reply to me – it is very argent for me.. thanks!

    Regards,
    Paresh

  23. Paul Says:

    I’ve went thru this whole thing twice. It compiles and installs with no errors. I see one entry in the event log and that’s it. I refresh after a minute or 2 goes by…still nothing. I am using the Event viewer. This is where it should be showing up, right?


Leave a Reply