In the code editor for MyNewService.cs or MyNewService.vb, locate the OnStart method. Visual Studio automatically created an empty method definition when you created the project. Add code that writes an entry to the event log when the service starts:
Because a service application is designed to be long-running, it usually polls or monitors the system, which you set up in the OnStart method. The OnStart method must return to the operating system after the service's operation has begun so that the system isn't blocked.
To set up a simple polling mechanism, use the System.Timers.Timer component. The timer raises an Elapsed event at regular intervals, at which time your service can do its monitoring. You use the Timer component as follows:
Services report their status to the Service Control Manager so that a user can tell whether a service is functioning correctly. By default, a service that inherits from ServiceBase reports a limited set of status settings, which include SERVICE_STOPPED, SERVICE_PAUSED, and SERVICE_RUNNING. If a service takes a while to start up, it's useful to report a SERVICE_START_PENDING status.
The Service Control Manager uses the dwWaitHint and dwCheckpoint members of the SERVICE_STATUS structure to determine how much time to wait for a Windows service to start or shut down. If your OnStart and OnStop methods run long, your service can request more time by calling SetServiceStatus again with an incremented dwCheckPoint value.
By default, Visual Studio adds a component class named ProjectInstaller, which contains two installers, to your project. These installers are for your service and for the service's associated process.
In the Design view for ProjectInstaller, select serviceInstaller1 for a Visual C# project, or ServiceInstaller1 for a Visual Basic project, then choose Properties from the shortcut menu.
This text appears in the Display Name column of the Services window. This name can be different from the ServiceName property, which is the name the system uses (for example, the name you use for the net start command to start your service).
In the Design view for ProjectInstaller, choose serviceProcessInstaller1 for a Visual C# project, or ServiceProcessInstaller1 for a Visual Basic project, then choose Properties from the shortcut menu. Set the Account property to LocalSystem from the drop-down list.
Before you decide to add startup parameters, consider whether it's the best way to pass information to your service. Although they're easy to use and parse, and a user can easily override them, they might be harder for a user to discover and use without documentation. Generally, if your service requires more than just a few startup parameters, you should use the registry or a configuration file instead.
A Windows service can accept command-line arguments, or startup parameters. When you add code to process startup parameters, a user can start your service with their own custom startup parameters in the service properties window. However, these startup parameters aren't persisted the next time the service starts. To set startup parameters permanently, set them in the registry.
Each Windows service has a registry entry under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services subkey. Under each service's subkey, use the Parameters subkey to store information that your service can access. You can use application configuration files for a Windows service the same way you do for other types of programs. For sample code, see ConfigurationManager.AppSettings.
Select Program.cs, or MyNewService.Designer.vb, then choose View Code from the shortcut menu. In the Main method, change the code to add an input parameter and pass it to the service constructor:
Typically, this value contains the full path to the executable for the Windows service. For the service to start up correctly, the user must supply quotation marks for the path and each individual parameter. A user can change the parameters in the ImagePath registry entry to change the startup parameters for the Windows service. However, a better way is to change the value programmatically and expose the functionality in a user-friendly way, such as by using a management or configuration utility.
In Windows, open the Services desktop app. Press Windows+R to open the Run box, enter services.msc, and then press Enter or select OK.
Locate the listing for MyNewLog (or MyLogFile1 if you followed the procedure to add command-line arguments) and expand it. You should see the entries for the two actions (start and stop) that your service performed.
Create a standalone setup program for others to use to install your Windows service. Use the WiX Toolset to create an installer for a Windows service. For other ideas, see Create an installer package.
Unlike regular software that is launched by the end user and only runs when the user is logged on, Windows Services can start without user intervention and may continue to run long after the user has logged off. The services run in the background and will usually kick in when the machine is booted. Developers can create Services by creating applications that are installed as a Service, an option ideal for use on servers when long-running functionality is needed without interference with other users on the same system.
The services manage a wide variety of functions including network connections, speaker sound, data backup, user credentials and display colors. Windows Services perform a similar function as UNIX daemons.
Windows Services are managed via the Services Control Manager panel. The panel shows a list of services and for each, name, description, status (running, stopped or paused) and the type of service. Double clicking on a service reveals its properties in greater detail. You can stop, pause, start, delay start, or resume each service as appropriate. You can also modify the start mechanism (Manual or Automatic) or specify an account.
Windows Services broadly fall into three categories depending on the actions and applications they control: Local Services, Network Services and System. Third party applications such as antivirus software may also install their own services.
Developers often use Services for functions that are necessary to run in the background, such as the ability to monitor performance data and react to specified thresholds. Services can also be created as Microsoft Visual Studio projects, developing code that specifies what commands can be sent to the service as well as what actions are taken on receipt of those commands. For more specifics on using Visual Studio projects to create Services, check out our recent post on how to create .NET Core Windows Services with Visual Studio 2017.
If you run your services as console for debugging, the Trace will output to the console by default. I've taken to using Trace instead of Debug or Console writes since I can, from the config file, output the trace information to any combination of files, screen, database, etc.
The output was always discarded until Windows Server 2008R2. Leave a console.writeline() in a service installed on that OS, and you'll get an error 1067 when starting/running the service, depending on the position of the writeline().
In .NET Core 3.0 we are introducing a new type of application template called Worker Service. This template is intended to give you a starting point for writing long running services in .NET Core. In this walkthrough we will create a worker and run it as a Windows Service.
First, lets publish the application. We will install the Windows Service in-place, meaning the exe will be locked whenever the service is running. The publish step is a nice way to make sure all the files I need to run the service are in one place and ready to be installed.
Please consider adding an option to override PreshutdownTimeout and/or to extend ServiceBase and ServiceInstaller and use those classes.
Currently, I have my own base class that allows me to extend preshutdown timeout, because I want the current operation to finish before I shut down service.
Having the ability to extend (override) the default preshutdown timeout would be awesome!
How do I set the server configuration for WildFly running as a Windows Service? The service batch file only seems to have options for installing in standalone or domain modes with the default configuration files. I want to have separate instances running for the different demos I have on a server, I can do it by setting the configuration when starting manually but can't find anything about doing this when starting as a service. Of course I can just duplicate the entire WildFly instance and modify standalone.xml for each, but I was hoping to avoid that.
If you're more adventurous, you might try mucking with bin/service/service.bat to make it so you can pass arbitrary parameters to standalone.bat/domain.bat, which would then allow you to create multiple services with different configurations.
Thanks for the reply Rich. From what I can tell service.bat sets a bunch of things then calls wildfly-service.exe with various arguments, and I can't find anything that tells me what I could add to that to change the configuration. Also looking at the service details in the registry there's nothing about parameters being passed. So it looks like for the moment I'm either going to have to replicate everything, or go back to using JavaService as we did for previous versions of JBoss AS.
The WildFly developers implemented the service stuff using Apache Commons Daemon, which is not very good in my experience. You're correct that it stores stuff in the registry, and I think that could be used to pass additional parameters, but not without some major surgery on the service.bat script. The key is the %STARTPARAM% variable. It looks like that ultimately just calls standalone.bat, and you can pass -c=my-config.xml to standalone.bat. So the trick is to be able to add arguments to STARTPARAM, which the current service.bat doesn't allow.
760c119bf3