A crate that provides facilities for management and implementation of windows services.
This section describes the steps of implementing a program that runs as a windows service, for complete source code of such program take a look at examples folder.
Each windows service has to implement a service entry function fn(argc: u32, argv: *mut *mut
u16)
and register it with the system from the application's main
.
This crate provides a handy [define_windows_service!
] macro to generate a low level
boilerplate for the service entry function that parses input from the system and delegates
handling to user defined higher level function fn(arguments: Vec<OsString>)
.
This guide references the low level entry function as ffi_service_main
and higher
level function as my_service_main
but it's up to developer how to call them.
```rust
extern crate windows_service;
use std::ffi::OsString; use windowsservice::servicedispatcher;
definewindowsservice!(ffiservicemain, myservicemain);
fn myservicemain(arguments: Vecservice_dispatcher::start
from main
.
}
fn main() -> Result<(), windowsservice::Error> {
// Register generated ffi_service_main
with the system and start the service, blocking
// this thread until the service is stopped.
servicedispatcher::start("myservice", ffiservicemain)?;
Ok(())
}
```
The first thing that a windows service should do early in its lifecycle is to subscribe for service events such as stop or pause and many other.
```rust extern crate windows_service;
use std::ffi::OsString; use windowsservice::service::ServiceControl; use windowsservice::servicecontrolhandler::{self, ServiceControlHandlerResult};
fn myservicemain(arguments: Vec
fn runservice(arguments: Vec
// Register system service event handler
let status_handle = service_control_handler::register("myservice", event_handler)?;
Ok(())
} ```
Please see the corresponding MSDN article that describes how event handler works internally:\ https://msdn.microsoft.com/en-us/library/windows/desktop/ms685149(v=vs.85).aspx
When application that implements a windows service is launched by the system, it's
automatically put in the [StartPending
] state.
The application needs to complete the initialization, obtain [ServiceStatusHandle
] (see
[service_control_handler::register
]) and transition to [Running
] state.
If service has a lengthy initialization, it should immediately tell the system how
much time it needs to complete it, by sending the [StartPending
] state, time
estimate using [ServiceStatus::wait_hint
] and increment [ServiceStatus::checkpoint
] each
time the service completes a step in initialization.
The system will attempt to kill a service that is not able to transition to [Running
]
state before the proposed [ServiceStatus::wait_hint
] expired.
The same concept applies when transitioning between other pending states and their corresponding target states.
Note that it's safe to clone [ServiceStatusHandle
] and use it from any thread.
```rust extern crate windows_service;
use std::ffi::OsString; use std::time::Duration; use windowsservice::service::{ ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus, ServiceType, }; use windowsservice::servicecontrolhandler::{self, ServiceControlHandlerResult};
fn myservicemain(arguments: Vec
fn runservice(arguments: Vec
// Register system service event handler
let status_handle = service_control_handler::register("my_service_name", event_handler)?;
let next_status = ServiceStatus {
// Should match the one from system service registry
service_type: ServiceType::OWN_PROCESS,
// The new state
current_state: ServiceState::Running,
// Accept stop events when running
controls_accepted: ServiceControlAccept::STOP,
// Used to report an error when starting or stopping only, otherwise must be zero
exit_code: ServiceExitCode::Win32(0),
// Only used for pending states, otherwise must be zero
checkpoint: 0,
// Only used for pending states, otherwise must be zero
wait_hint: Duration::default(),
};
// Tell the system that the service is running now
status_handle.set_service_status(next_status)?;
// Do some work
Ok(())
} ```
Please refer to the "Service State Transitions" article on MSDN for more info:\ https://msdn.microsoft.com/en-us/library/windows/desktop/ee126211(v=vs.85).aspx
License: MIT/Apache-2.0