Write a service isn't allways easy, specialy when you have a lot of existing code to deal with. The OSR_Service toolkit is a set of C files you can include into your C/C++ projects to write window services functionalities in few lines.
The ServiceStart function
The ServiceStart function start the service. It may be called at the begin of the application.
OSR_ERROR OSR_CALL ServiceStart(OSR_SERVICE_PARAMS * Params)
Pointer to the
OSR_SEVICE_PARAMS structure the contains the servis start parameters and preferences.
If the function succeeds, the return value is OSR_SUCCESS.
Ideally, this function must be called in the main function (
) before the the code the application may execute when the service is running.
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
params.ServiceDependencies = 0;
params.ServiceDependencies = 0;
strcpy((char *)params.ServiceNameDisplay,"OSR sample service");
params.ServiceAcceptedCommands = SERVICE_ACCEPT_STOP|
params.ServiceStartType = SERVICE_DEMAND_START;
if(strcmp(lpCmdLine,"install") == 0)
// Install the service
if(strcmp(lpCmdLine,"uninstall") == 0)
// Uninstall the service
// Start the service
// The service is now running
// Do something
printf("I'm a running service\n");
The OSR_APP_XXX Functions
Four callback functions must be wrote by the user to handle the service messages. This functions are :
int OSR_CALL OSR_APP_START(int step);
int OSR_CALL OSR_APP_STOP(int step);
int OSR_CALL OSR_APP_PAUSE(int step);
int OSR_CALL OSR_APP_CONTINUE(int step);
int OSR_CALL OSR_APP_SHUTDOWN(int step);
When the service receives a message form the service manager, requisting for a new status (eg. the service is running, and we want to stop it), the
OSR_APP_STOP is called one time. According to the returned value by this function, the function will be called as long as is necesary to complete the stop process.
As decribed in the fig 1., a service has 3 major states (
) and 4 pending states (
) . fig1. service states
The major states are states requested by a service manager (eg. stop the service), and the pending states are transitory states between 2 major states. A way to the application to say to the service manager "Ok! I'm doing the required things to stop the application, please wait".
The step is an incremential value sent to the function every time the function is called under the same status change.
The function can return 3 values
|The init process is not completed, the service stay in a pending state, and this function will be called again and the step value increased.|
|The init process is completed. The service can be in the requested state.|
|The init process can't be done, or fail. The status can't be changed.|
All these functions must be return a result to allow the status update.
For the OSR_APP_START function, you may launch a new thread to run something after the start initialization.
Here a simple start process in 3 steps.
int OSR_CALL OSR_APP_START(int step)
The OSR_SERVICE_PARAMS structure
typedef struct _OSR_SERVICE_PARAMS
// Name of the service
// Service name displayed in the service manager
// Dependencies name array
// Service start mode
// Login used by the service
// Password used by the service
// Commands you can use with this service
Null-terminated string that names the service. "\" and "/" characters are invalid in the service name.
Null-terminated string that is to be used by user interface programs to identify the service.
Double null-terminated array of null-separated names of services or load ordering groups that the system must start before this service. Specify NULL if no dependencies are required.
- "NetworkService\0LogService\0\0" means NetworkService and LogService may be started before allow your service to start.
- "\0\0" means no dependencied are defined.
Specifies when to start the service. You must specify one of the following start types
|Specifies a service to be started automatically by the service control manager during system startup. |
|Specifies a service to be started by the service control manager when a process calls the StartService function.|
|Specifies a service that can no longer be started.|
Null-terminated string that names the service. You must use an account name in the form DomainName\UserName. Because the account belongs to the built-in domain, you can specify .\UserName. You also must specify the LocalSystem account. If you specify an empty string ("\0") LocalSystem account is used.
Null-terminated string that contains the password to the account name specified by the ServiceLogin parameter. If the string is empty, the service has no password.
Using the sample
This project is provided with a sample project who demostrate how to integrate the osr_service code in "real" code. The sample code include a precompiled binary - for X86 win32 platforms - who run in this way.
sample_service [install|uninstall] to install or remove the service from the service manager. For your convenience I build it with the system account, ie. no change is require for a first try.
The sample, and basicaly all the osr_service functions run in a debug mode, who log all the errors using the OutputDebugString log method. To display the logs you must use a tool like DebugView
from the SysInternals guys (www.sysinternals.com
). This tool is free.