Параметр dwControlCode, если доступ разрешен, может принимать одно из следующих значений:
SERVICE_CONTROL_STOP
SERVICE_CONTROL_PAUSE
SERVICE_CONTROL_CONTINUE
SERVICE_CONTROL_INTERROGATE
SERVICE_CONTROL_SHUTDOWN
или значение, определенное пользователем, лежащее в пределах диапазона 128–255. Эти значения совпадают с теми, которые использовались вместе с флагом dwControl в функции ServerCtrlHandler.
lpServStat — указатель на структуру SERVICE_STATUS, которая получает текущее состояние. Это та же структура, которая использовалась функцией SetServiceStatus.
Опрос состояния службы
Для получения структурой SERVICE_STATUS текущего состояния службы используется следующая функция:
BOOL QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Резюме: функционирование и управление службой
На рис. 13.1 показано, каким образом SCM связан со службами и программой управления службами, подобной программе 13.3, которая рассматривается в следующем разделе. В частности, SCM должен зарегистрировать службу, и все команды, предназначенные для службы, должны пропускаться через SCM.
Рис. 13.1. Управление службами Windows через SCM
Пример:команднаяоболочкауправленияслужбами
Управление службами часто осуществляется посредством утилит, входящих в группу Administrative Tools, доступ к которым открывается через пиктограмму Services (Службы). Для управления пользовательскими службами можно также использовать оболочку ServiceShell (программа 13.3), представляющую собой видоизмененный вариант программы JobShell из главы 6 (программа 6.3).
/* Глава 13. */
/* ServiceShell.с. Программа командной оболочки управления службами Windows.
Эта программа является видоизмененным вариантом программы управления задачами из главы 6, но только управляет службами, а не задачами. */
/* Поддерживаемые команды:
create — создание службы
delete – удаление службы
start – запуск службы
control – управление службой */
#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; /* Локальный параметр argc. */
TCHAR argstr[MAX_ARG][MAX_COMMAND_LINE];
LPTSTR pArgs[MAX_ARG];
/* Подготовить локальный массив "argv" в виде указателей на строки. */
for (i = 0; i < MAX_ARG; i++) pArgs[i] = argstr[i];
/* Открыть диспетчер управления службами на локальной машине. */
hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
/* Главный цикл обработки команд. */
_tprintf(_T("\nУправление службами Windows Services"));
while (!Exit) {
_tprintf(_T ("\nSM$"));
_fgetts(Command, MAX_COMMAND_LINE, stdin);
… Как для JobShell …
if (_tcscmp(argstr [0], _T("create")) == 0) {
Create(LocArgc, pArgs, Command);
}
… Аналогичным образом для всех команд …
}
CloseServiceHandle(hScm);
return 0;
}
int Create(int argc, LPTSTR argv[], LPTSTR Command) {
/* Создание новой службы в виде службы, запускаемой "по требованию":
argv[1]: имя службы
argv[2]: отображаемое имя службы
argv[3]: название исполняемого файла */
SC_HANDLE hSc;
TCHAR CurrentDir[MAX_PATH +1], Executable[MAX_PATH + 1];