I know that writing of service programs is quite difficult for beginners.
In this post I'm publishing simple working example.
This service only beeps with one second's interval after starts.
service.c
#include <windows.h>
HANDLE hServerStopEvent = NULL;
VOID ServiceBody();
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
VOID WINAPI ServiceControlHandler(DWORD dwCtrlCode);
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
SERVICE_STATUS ssStatus;
SERVICE_STATUS_HANDLE sshStatusHandle;
void _cdecl main(int argc, char **argv)
{
SERVICE_TABLE_ENTRY dispatchTable[] =
{{"", (LPSERVICE_MAIN_FUNCTION)ServiceMain }, { NULL, NULL }};
StartServiceCtrlDispatcher(dispatchTable);
}
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
sshStatusHandle = RegisterServiceCtrlHandler( "", ServiceControlHandler);
if (!sshStatusHandle)
goto cleanup;
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;
if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
goto cleanup;
ServiceBody();
cleanup:
if (sshStatusHandle)
(VOID)ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);
return;
}
VOID WINAPI ServiceControlHandler(DWORD dwCtrlCode)
{
if(dwCtrlCode==SERVICE_CONTROL_STOP)
{
ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
if ( hServerStopEvent )
SetEvent(hServerStopEvent);
}
ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
}
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
{
if (dwCurrentState == SERVICE_START_PENDING)
ssStatus.dwControlsAccepted = 0;
else
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
if ( ( dwCurrentState == SERVICE_RUNNING )
|| ( dwCurrentState == SERVICE_STOPPED ) )
ssStatus.dwCheckPoint = 0;
else
ssStatus.dwCheckPoint++;
return SetServiceStatus( sshStatusHandle, &ssStatus);
}
//This sample only beeps.
VOID ServiceBody ()
{
hServerStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hServerStopEvent)
goto cleanup;
if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0))
goto cleanup;
do
{
MessageBeep(-1);
} while (WaitForSingleObject(hServerStopEvent, 1000 )== WAIT_TIMEOUT);
cleanup:
if (hServerStopEvent)
CloseHandle(hServerStopEvent);
}
Script for compiling with Visual C++ 6.0:
make_vc6.bat
@call "D:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
@cl /nologo service.c user32.lib advapi32.lib
@del service.obj
If you use Visual C++ Express, you need additional Platform SDK from Microsoft.
Install (register) service via command:
service_create.bat
sc create "XQX Service" binPath= %CD%\service.exe
Start service via command:
service_start.bat
net start "XQX Service"
Stop service via command:
service_stop.bat
net stop "XQX Service"
Uninstall (remove) service via command:
service_delete.bat
sc delete "XQX Service"