Services are frequently controlled from the Administrative Tools, where there is a "Services" icon. Alternatively, you can control user-developed services using ServiceShell (Chapter 6's JobShell (Program 6-3).
/* Chapter 13. */ /* ServiceShell.c Windows service management shell program. This program modifies Chapter 6's job management program, managing services rather than jobs. */ /* Commands supported are: create -- create a service delete -- delete a service start -- start a service control -- control a service */ #include "EvryThng.h" static SC_HANDLE hScm; static BOOL Debug; int _tmain (int argc, LPTSTR argv []) { BOOL Exit = FALSE; TCHAR Command [MAX_COMMAND_LINE + 10], *pc; DWORD i, LocArgc; /* Local argc. */ TCHAR argstr [MAX_ARG] [MAX_COMMAND_LINE]; LPTSTR pArgs [MAX_ARG]; /* Prepare the local "argv" array as pointers to strings. */ for (i = 0; i < MAX_ARG; i++) pArgs [i] = argstr [i]; /* Open the SC Control Manager on the local machine. */ hScm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); /* Main command processing loop. */ _tprintf (_T ("\nWindows Service Management")); while (!Exit) { _tprintf (_T ("\nSM$")); _fgetts (Command, MAX_COMMAND_LINE, stdin); ... Similar to JobShell ... if (_tcscmp (argstr [0], _T ("create")) == 0) { Create (LocArgc, pArgs, Command); } ... Similarly for all commands ... } CloseServiceHandle (hScm); return 0; } int Create (int argc, LPTSTR argv [], LPTSTR Command) { /* Create a new service as a "demand start" service: argv [1]: service Name argv [2]: display Name argv [3]: binary executable */ SC_HANDLE hSc; TCHAR CurrentDir [MAX_PATH + 1], Executable [MAX_PATH + 1]; hSc = CreateService (hScm, argv [1], argv [2], SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, Executable, NULL, NULL, NULL, NULL, NULL); return 0; } /* Delete a service -- argv [1]: ServiceName to delete. */ int Delete (int argc, LPTSTR argv [], LPTSTR Command) { SC_HANDLE hSc; hSc = OpenService (hScm, argv [1], DELETE); DeleteService (hSc); CloseServiceHandle (hSc); return 0; } /* Start a named service -- argv [1]: service name to start. */ int Start (int argc, LPTSTR argv [], LPTSTR Command) { SC_HANDLE hSc; TCHAR WorkingDir [MAX_PATH + 1]; LPTSTR pWorkingDir = WorkingDir; LPTSTR argvStart [] = {argv [1], WorkingDir}; GetCurrentDirectory (MAX_PATH + 1, WorkingDir); hSc = OpenService(hScm, argv [1], SERVICE_ALL_ACCESS); /* Start the service with one arg, the working directory. */ /* Note: The service name agrees, by default, with the name */ /* associated with the handle, hSc, by OpenService. */ /* But, the ServiceMain function does not verify this. */ StartService (hSc, 2, argvStart); CloseServiceHandle (hSc); return 0; } /* Control a named service. argv [1]: service name to control. argv [2]: Control command: stop, pause, resume, interrogate. */ static LPCTSTR Commands [] = {"stop," "pause," "resume," "interrogate," "user"}; static DWORD Controls [] = { SERVICE_CONTROL_STOP, SERVICE_CONTROL_PAUSE, SERVICE_CONTROL_CONTINUE, SERVICE_CONTROL_INTERROGATE, 128}; int Control (int argc, LPTSTR argv [], LPTSTR Command) { SC_HANDLE hSc; SERVICE_STATUS ServiceStatus; DWORD dwControl, i; BOOL Found = FALSE; for (i= 0; i < sizeof (Controls)/sizeof (DWORD) && !Found; i++) Found = (_tcscmp (Commands [i], argv [2]) == 0); if (!Found) { _tprintf (_T ("\nIllegal Control Command %s"), argv [1]); return 1; } dwControl = Controls [i - 1]; hSc = OpenService(hScm, argv [1], SERVICE_INTERROGATE | SERVICE_PAUSE_CONTINUE | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL | SERVICE_QUERY_STATUS); ControlService (hSc, dwControl, &ServiceStatus); if (dwControl == SERVICE_CONTROL_INTERROGATE) { QueryServiceStatus (hSc, &ServiceStatus); printf (_T ("Status from QueryServiceStatus\n")); printf (_T ("Service Status\n")); ... Print all other status information ... } if (hSc != NULL) CloseServiceHandle (hSc); return 0; }