| Автор
| Сообщение |
|
|
|
Цитата |
|
Подскажите, пожалуйста, как можно програмно останавливать и запускать сервисы WinNT, устанавливать тип запуска (Automatic/Manual/Disabled), а также узнавать их текущее состояние ?
Я знаю один способ, но он мне очень не нравится - это запуска с помощью WinExec cmd-файла с командой NET START Service.
Тип запуска можно менять редактируя реестр, но изменения вступят в силу лишь после перезагрузки системы.
Хотелось бы иметь в своем распоряжении инструмент, позволяющий производить все те действия, что доступны для выполнения на апплете панели управления Services |
|
| В начало |
|
 |
|
|
 |
 Ktf
Администратор

Возраст: 32
Знак зодиака: 
Зарегистрирован: 15.05.2005
Сообщения: 1502
Откуда: localhost
|
|
|
Цитата |
|
прежде чем что-то делать, подключаемся к контроллеру служб (для этого должны быть админские права)
| Код: |
var
SvcMgr: Integer;
....
SvcMgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if SvcMgr=0 then Error;
|
устанавливаем службу
| Код: |
var
svc: integer;
...
Svc := CreateService(SvcMgr,
'Внутреннее имя службы',
'Отображаемое имя службы',
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
PChar('Путь к исполняемому файлу'),
nil,
nil,
nil,
nil,
nil);
if Svc=0 then Error;
// если задача состояла только в установке службы, освобождаем хендл
CloseServiceHandle(Svc);
|
управляем службой
получаем хэндл службы
| Код: |
Svc := OpenService(SvcMgr, 'Внутреннее имя службы', SERVICE_ALL_ACCESS);
if Svc=0 then Error;
|
запускаем службу
| Код: |
var
ArgV: Pchar;
...
ArgV:=nil;
if not StartService(Svc,0,ArgV) then Error;
|
останавливаем службу
| Код: |
var
ss: _SERVICE_STATUS;
...
if not ControlService(Svc,SERVICE_CONTROL_STOP,ss) then Error;
|
удаляем службу
| Код: |
if not DeleteService(Svc) then Error;
|
продолжение следует...  |
|
| В начало |
|
 |
 Ktf
Администратор

Возраст: 32
Знак зодиака: 
Зарегистрирован: 15.05.2005
Сообщения: 1502
Откуда: localhost
|
|
|
Цитата |
|
чуть не забыл!
когда все манипуляции закончили, не забываем соответствующие освободить хендлы!
| Код: |
if Svc<>0 then
CloseServiceHandle(Svc); // хендл службы
|
а затем
| Код: |
if SvcMgr<>0 then
CloseServiceHandle(SvcMgr); // хендл контроллера (диспетчера, менеджера, да как угодно) служб
|
|
|
| В начало |
|
 |
 Gelios
Oracle-вый маньяк, Админ

Возраст: 37
Знак зодиака: 
Зарегистрирован: 10.03.2005
Сообщения: 6141
Откуда: Яблочный рай
|
|
|
Цитата |
|
to Ktf
помести это в FAQ _________________ нельзя давать всем всего, ибо всех много, а всего мало |
|
| В начало |
|
 |
|
|
|
Цитата |
|
| Спасибо, Ktf, за исчерпывающий ответ |
|
| В начало |
|
 |
 Ktf
Администратор

Возраст: 32
Знак зодиака: 
Зарегистрирован: 15.05.2005
Сообщения: 1502
Откуда: localhost
|
|
|
Цитата |
|
получаем состояние службы
| Код: | var
pSS: SERVICE_STATUS;
...
if not QueryServiceStatus(Svc, pSS) then exit;
// pSS.dwCurrentState содержит текущее состояние
|
|
|
| В начало |
|
 |
 Ktf
Администратор

Возраст: 32
Знак зодиака: 
Зарегистрирован: 15.05.2005
Сообщения: 1502
Откуда: localhost
|
|
|
Цитата |
|
изменяем конфигурацию службы
перед изменением конфигурации блокируем базу данных служб
| Код: | var
SvcLock: SC_LOCK;
...
SvcLock:=LockServiceDatabase(SvcMgr);
if SvcLock=nil then Error; |
выполняем изменение конфигурации
| Код: | if not ChangeServiceConfig(
Svc, // хендл службы
SERVICE_NO_CHANGE, // без изменений
SERVICE_DEMAND_START, // изменяем тип запуска (Вручную)
SERVICE_NO_CHANGE, // без изменений
nil, // без изменений
nil, // без изменений
nil, // без изменений
nil, // без изменений
nil, // без изменений
nil) // без изменений
then Error; |
не забываем разблокировать базу данных служб
| Код: | | UnlockServiceDatabase(SvcLock); |
Ну вот, кажется, и все.
И не забываем освобождать хендлы.  |
|
| В начало |
|
 |
|