-
Notifications
You must be signed in to change notification settings - Fork 3
Windows Service
This package provides methods for managing windows services.
Before you start see main prerequisites. Create shell instance:
var factory = new ContinuousManagementFactory();
var _shell = factory.WindowsServiceShell();- Get
- Get all
- Install
- Update
- Uninstall
- Start
- Stop
- Pause
- Continue
- Change account
- Get state
- Refresh
- Wait for state
- Exists
- Execute command
- Batch operations
Get comprehensive information about service:
WindowsServiceInfo service = _shell.Get(serviceName);where serviceName is windows service name. It will return null if service not found.
Create new WindowsServiceInfo instance and fetch information about service:
WindowsServiceInfo service = new WindowsServiceInfo(serviceName);If service with provided serviceName is not existing the InvalidOperationException will occur.
Get list of all available windows services:
List<WindowsServiceInfo> services = _shell.GetAll();simple
Install service by providing only name and path to service file:
_shell.Install(serviceName, servicePath);servicePath is full path to service executable file, like "C:\Test\bin\WindowsServcie.exe" If you provide wrong Path the FileNotFoundException will occur.
advanced
Install service by providing full service-options class:
var configuration = new WindowsServiceConfiguration()
{
Name = "TestService2",
Path = "C:\\CompiledTestService\\EmptyTestService.exe"
};
_shell.Install(configuration);In the simplest usage of installing service with custom configuration you must provide at least Name and Path.
Possible WindowsServiceConfiguration properties:
| Parameter | Description |
|---|---|
| Name | Name of the service to install |
| Description | Service description |
| DisplayName | Display name of the service |
| Path | Fully qualified path to the service binary file |
| AccountName | Account name under which the service runs |
| AccountDomain | Account domain. Local domain as default |
| AccountPassword | Account password |
| DriverName | Driver object name for kernel and system-level drivers |
| Type | Type of process which will be invoking this service. OwnProcess as default |
| ErrorControl | Severity of the error if the Create method fails to start |
| StartMode | Start mode of the Windows base service. Auto as default |
| ServiceDependencies | Collection of services names that must run before this service will start |
| InteractWithDesktop | If true, the service can create or communicate with windows on the desktop. False as default |
If Path not contains any file the FileNotFoundException will occur.
If AccountName or AccountPassword is invalid, the InvalidOperationException will occur.
Update existing service:
var serviceName = "testService";
var configuration = new WindowsServiceConfigurationForUpdate
{
DisplayName = "changed display name",
Type = WindowsServiceType.ShareProcess,
ErrorControl = WindowsServiceErrorControl.Severe,
InteractWithDesktop = true,
StartMode = WindowsServiceStartMode.Disabled
};
_shell.Update(serviceName, configuration);All fields from WindowsServiceConfigurationForUpdate with assigned value will be updated. Leave null if you do not want to update field.
Possible WindowsServiceConfigurationForUpdate properties:
| Parameter | Description |
|---|---|
| Description | Service description |
| DisplayName | Display name of the service |
| Path | Fully qualified path to the service binary file |
| Type | Type of process which will be invoking this service. OwnProcess as default |
| ErrorControl | Severity of the error if the Create method fails to start. |
| StartMode | Start mode of the Windows base service. Auto as default |
| ServiceDependencies | Collection of services names that must run before this service will start |
| InteractWithDesktop | If true, the service can create or communicate with windows on the desktop. False as default |
It is not possible to update account (user) with this method. To update account, use _shell.ChangeAccount method.
If service with provided serviceName is not existing the InvalidOperationException will occur.
If Path not contains any file the FileNotFoundException will occur.
It is possible to update all fields mentioned above (+ account properties) directly from WindowsServiceInfo instance:
var service = new WindowsServiceInfo(serviceName); // create instance
service.Change() // start update process
.Description(newDescription) // set fields to update
.DisplayName(newDisplayName)
.Path(newPath)
.Type(newType)
.ErrorControl(newErrorControl)
.StartMode(newStartMode)
.ServiceDependencies(newServiceDependencies)
.InteractWithDesktop(newInteractWithDesktop)
.AccountName(newAccountName)
.AccountPassword(newAccountPassword)
.AccountDomain(newAccountDomain)
.Apply(); // apply changesIt is very important to invoke Apply() at the end of the process to save all changes. Otherwise none of fields will be updated.
If Path not contains any file the FileNotFoundException will occur.
If service is not existing, the InvalidOperationException will occur.
Rollback on error
Update process contains two steps:
- Update Service
- Update Service Account
If step 2 throws error (and not executed), step 1 will be still executed, so changes from step 1 will be saved. To prevent this behavior you can invoke RollbackOnError() method during update process:
var service = new WindowsServiceInfo(serviceName);
service.Change() // start update proccess
.AccountName("fakeAccount") // set service account properties
.AccountDomain("fakeDomain")
.Description("new description") // set service properties
.RollbackOnError() // prevent from updating service on error
.Apply(); // apply changesThere is no need to invoke RollbackOnError() when you are not changing service and service account properties in the same time.
Uninstall process even if is running:
_shell.Uninstall(serviceName); if you provide wrong serviceName the InvalidOperationException will occur.
Uninstall current instance of WindowsServiceInfo:
var service = new WindowsServiceInfo(serviceName);
service.Uninstall();If service is not existing, the InvalidOperationException will occur.
Start not-running service:
_shell.Start(serviceName);Returns true when service was successfully started. If you try start already running service, method will return false as a result.
If service is not existing, the InvalidOperationException will occur.
Start current instance of WindowsServiceInfo:
var service = new WindowsServiceInfo(serviceName);
service.Start(); // start service and wait for 'Running' stateIf service is not existing, the InvalidOperationException will occur.
Start() method has default WaitForState parameter set to true. You can force not waiting for state behavior:
service.Start(false); // will not wait for 'Running' state Stop running service:
_shell.Stop(serviceName);Returns true when service was successfully started. If you try stop already stopped service, method will return false.
If service is not existing, the InvalidOperationException will occur.
Stop current instance of WindowsServiceInfo:
var service = new WindowsServiceInfo(serviceName);
service.Stop(); // Stop service and wait for 'Stopped' stateIf service is not existing, the InvalidOperationException will occur.
Stop() method has default WaitForState parameter set to true. You can force not waiting for state behavior:
service.Stop(false); // will not wait for 'Stopped' state Pause running service:
_shell.Pause(serviceName);Returns true when service was successfully paused. If you try pause not running service, method will return false.
If service is not existing, the InvalidOperationException will occur.
Pause current instance of WindowsServiceInfo:
var service = new WindowsServiceInfo(serviceName);
service.Pause(); // pause service and wait for 'Paused' stateIf service is not existing, the InvalidOperationException will occur.
Pause() method has default WaitForState parameter set to true. You can force not waiting for state behavior:
service.Pause(false); // will not wait for 'Paused' state Resume paused service:
_shell.Continue(serviceName);If service is not existing, the InvalidOperationException will occur.
Returns true when service was successfully resumed. If you try resume not paused service, method will return false.
Resume current instance of WindowsServiceInfo:
var service = new WindowsServiceInfo(serviceName);
service.Continue(); // resume service and wait for 'Running' stateIf service is not existing, the InvalidOperationException will occur.
Continue() method has default WaitForState parameter set to true. You can force not waiting for state behavior:
service.Continue(false); // will not wait for 'Running' state Change account on which service is currently running:
_shell.ChangeAccount("serviceName", "accountName", "accountPassword", "accountDomain");You can leave domain property empty or '.' to provide local domain.
If service is not existing, the InvalidOperationException will occur.
Update account is also possible by updating process in current WindowsServiceInfo instance:
var service = new WindowsServiceInfo(serviceName);
service.Change() // start update proccess
.AccountName("accountName") // set properties
.AccountPassword("accountName")
.AccountDomain(".")
.Apply(); // apply changesIt is very important to invoke Apply() at the end of the process to save all changes. Otherwise none of fields will be updated.
If service is not existing, the InvalidOperationException will occur.
Get service current state, commonly known as status:
_shell.GetState(serviceName);If service is not existing, the InvalidOperationException will occur.
Check current WindowsServiceInfo instance state:
var service = new WindowsServiceInfo(serviceName);
WindowsServiceState state = service.State;State (and other properties) will be updated after call service.Refresh() method.
If service is not existing, the InvalidOperationException will occur.
Refresh all fields in WindowsServiceInfo instance:
var service = new WindowsServiceInfo(serviceName);
service.Refresh();If service is not existing, the InvalidOperationException will occur.
Wait until service get expected state:
var serviceName = "testService";
var expetedState = WindowsServiceState.Running;
var timeout = TimeSpan.FromMilliseconds(1000);
_shell.WaitForState(serviceName, expectedState, timeout);timeout parameter is optional and as default shell will wait 1000 milliseconds.
If service is not existing, the InvalidOperationException will occur.
If service is waiting too long, the TimeoutException will occur.
Wait until current WindowsServiceInstance get expected state:
var service = new WindowsServiceInfo(serviceName);
service.WaitForState(WindowsServiceState.Running);If service is not existing, the InvalidOperationException will occur.
If service is waiting too long, the TimeoutException will occur.
Quick check if service with provided name exists:
_shell.Exists(serviceName);Returns true if service exist or false if not.
Check if current WindowsServiceInfo instance is still existing (for example has not been uninstalled in the meantime):
var service = new WindowsServiceInfo(serviceName);
service.Exists();Returns true if service exist or false if not.
If service is not existing during creating WindowsServiceInfo isntance, the InvalidOperationException will occur.
Send custom command signal to service:
int commandCode = 150; // range from 128 to 256
string serviceName = "testService";
_shell.ExecuteCommand(serviceName, commandCode);If service is not existing, the InvalidOperationException will occur.
If commandCode is out of range, the ArgumentException will occur.
Execute command on exinsting WindowsServiceInfo instance:
var service = new WindowsServiceInfo(serviceName);
int commandCode = 150; // range from 128 to 256
service.Execute(commandCode);if commandCode is out of range, the ArgumentException will occur.
If service is not existing, the InvalidOperationException will occur.
It is possible to invoke multiple methods in one call:
var service = new WindowsServiceInfo(serviceName);
// stop service, change description, start service
service.Stop()
.Change()
.Description("new description")
.Apply()
.Start();If service is not existing, the InvalidOperationException will occur.