Windows service: start and initialize C Win32 program example

 

#include <windows.h>

#include <stdio.h>

 

SERVICE_STATUS MyServiceStatus;

SERVICE_STATUS_HANDLE MyServiceStatusHandle;

 

void SvcDebugOut(LPSTR String, DWORD Status);

void WINAPI MyServiceCtrlHandler(DWORD opcode);

void WINAPI MyServiceStart(DWORD argc, LPTSTR *argv);

DWORD MyServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *specificError);

void main(void)

{

SERVICE_TABLE_ENTRY DispatchTable[] =

{

{L"TIntSvr", (LPSERVICE_MAIN_FUNCTIONW)MyServiceStart}, {NULL, NULL}

};

if (!StartServiceCtrlDispatcher(DispatchTable))

{

SvcDebugOut("StartServiceCtrlDispatcher() failed", GetLastError());

}

else

printf("StartServiceCtrlDispatcher() is OK\n");

}

 

VOID WINAPI MyServiceCtrlHandler(DWORD Opcode)

{

DWORD status;

switch(Opcode)

{

case SERVICE_CONTROL_PAUSE:

// Do whatever it takes to pause here.

MyServiceStatus.dwCurrentState = SERVICE_PAUSED;

break;

case SERVICE_CONTROL_CONTINUE:

// Do whatever it takes to continue here.

MyServiceStatus.dwCurrentState = SERVICE_RUNNING;

break;

case SERVICE_CONTROL_STOP:

// Do whatever it takes to stop here.

MyServiceStatus.dwWin32ExitCode = 0;

MyServiceStatus.dwCurrentState = SERVICE_STOPPED;

MyServiceStatus.dwCheckPoint = 0;

MyServiceStatus.dwWaitHint = 0;

 

if (!SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus))

{

status = GetLastError();

SvcDebugOut("SetServiceStatus() error", status);

}

SvcDebugOut("Leaving Telnet service", 0);

return;

case SERVICE_CONTROL_INTERROGATE:

// Fall through to send current status.

break;

default:

SvcDebugOut("Unrecognized opcode", Opcode);

}

// Send current status.

if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))

{

status = GetLastError();

SvcDebugOut("SetServiceStatus() error", status);

}

return;

}

 

void WINAPI MyServiceStart(DWORD argc, LPTSTR *argv)

{

DWORD status;

DWORD specificError;

MyServiceStatus.dwServiceType = SERVICE_WIN32;

MyServiceStatus.dwCurrentState = SERVICE_START_PENDING;

MyServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;

MyServiceStatus.dwWin32ExitCode = 0;

MyServiceStatus.dwServiceSpecificExitCode = 0;

MyServiceStatus.dwCheckPoint = 0;

MyServiceStatus.dwWaitHint = 0;

// If the function succeeds, the return value is a service status handle. If the function fails, the return value is zero.

MyServiceStatusHandle = RegisterServiceCtrlHandler(

L"TIntSvr",

MyServiceCtrlHandler); // function pointer

if (MyServiceStatusHandle == 0)

{

SvcDebugOut("RegisterServiceCtrlHandler() failed", GetLastError());

return;

}

else

printf("RegisterServiceCtrlHandler() is OK\n");

// Initialization code goes here.

status = MyServiceInitialization(argc, argv, &specificError);

// Handle error condition

if (status != NO_ERROR)

{

MyServiceStatus.dwCurrentState = SERVICE_STOPPED;

MyServiceStatus.dwCheckPoint = 0;

MyServiceStatus.dwWaitHint = 0;

MyServiceStatus.dwWin32ExitCode = status;

MyServiceStatus.dwServiceSpecificExitCode = specificError;

SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);

return;

}

// Initialization complete - report running status.

MyServiceStatus.dwCurrentState = SERVICE_RUNNING;

MyServiceStatus.dwCheckPoint = 0;

MyServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))

{

status = GetLastError();

SvcDebugOut("SetServiceStatus() error", status);

}

else

printf("SetServiceStatus() is OK\n");

// This is where the service does its work.

SvcDebugOut("Returning the Main Thread", 0);

return;

}

// Stub initialization function.

DWORD MyServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *specificError)

{

// Just dummy

argv;

argc;

specificError;

return 0;

}

VOID SvcDebugOut(LPSTR String, DWORD Status)

{

CHAR Buffer[1024];

 

if (strlen(String) < 1000)

{

sprintf_s(Buffer, sizeof(Buffer), String, Status);

 

// Check the output window at the bottom if you debug this program

OutputDebugStringA(Buffer);

 

// Or redirect to the standard output...

printf("The error message: %s, the error code: %ld\n", Buffer, Status);

}

}

 

Output example:

 

The error message: StartServiceCtrlDispatcher() failed, the error code: 1063

Press any key to continue . . .

ERROR_FAILED_SERVICE_CONTROLLER_CONNECT - (1063) The service process could not connect to the service controller

 

This is not a complete working example. Please refer to : Windows Services Programming with Win32 for a complete working example.

 

 

Compiler: Visual C++ Express Edition 2005

Compiled on Platform: Windows XP Pro SP2

Target platform: none, just for learning and fun

Header file: Standard and Windows

Additional library: [url=http://www.tenouk.com/clabworksheet/windowspsdk.html]Windows Platform SDK[/url]

Additional project setting: Set project to be compiled as C. Click Project menu->your_project_name Properties->Configuration Properties->C/C++->Advanced->Compiled As: Compiled as C Code (/TC)

Other info: non-CLR or unmanaged. Need to add Advapi32.lib (Advapi32.dll) to the project. Click the Project menu->Select the your_project_name Properties... sub menu->Expand the Configuration Properties folder on the left pane->Expand the Linker subfolder->Select the Input subfolder->Select the Additional Dependencies field on the right pane->Click the ... at the end of the field->Type in 'Advapi32.lib' in the empty pane->Click the OK button->Click the OK button second time to close the project Properties dialog.

To do: The Windows service Win32 programming: start and initialize

To show: Windows processes and services

 

 

C and C++ Programming Resources | C & C++ Code Example Index