Windows System Programming Third Edition [Electronic resources]

Johnson M. Hart

نسخه متنی -صفحه : 291/ 201
نمايش فراداده

  • Example: A Service Control Shell

    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).

    Program 13-3. ServiceShell: A Service Control Program
    /* 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;
    }