Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.11.04;
Скачать: CL | DM;

Вниз

как заставить Service Control Manager обновить "кэш" из реестра?   Найти похожие ветки 

 
Ketmar ©   (2007-04-25 16:33) [0]

ситуация такая: работает сервис. другая софтина делает DeleteService(). сервис помечается на удаление, но не удаляется, пока не завершится процесс сервиса. после чего SCM запись о сервисе убивает. никакие CreateService() наново и прочие не помогают сказать SCM, что убивать никого не надо. сервис как был disabled и marked for deletion, так и остаётся. до неминуемой смерти.

в реестре за это отвечает флажок "DeleteFlag". его грохнуть можно. НО. SCM на реестр плевать, SCM хранит всю инфу в каком-то своём "кэше". есть ли хотя бы "полуштатный" способ сказать SCM"у, что "кэш" надо почистить и перечитать всё из реестра?

tnx.


 
Rouse_ ©   (2007-04-25 17:56) [1]

А почемубы "другой софтине" сначала не дать команду сервису на остановку, после чего дождаться его завершения и только после этого вызвать DeleteService? И не нужно будет изобретать велосипед с перечитыванием кэша...


 
Ketmar ©   (2007-04-25 18:05) [2]

потому что "другая софтина" -- это юзер с FAR"ом, например. %-)

Розыч, если бы всё было решаемо такими методами, я бы не заморачивался подобными вопросами. суть тут в том, что "полугрохнутый" кривыми руками сервис надо вернуть на место. к сожалению, вариант "починить кривые руки" не проходит... %-(


 
Rouse_ ©   (2007-04-25 18:08) [3]

Ааа, так тебе вернуть его нужно :)
Ну тут нужно поэсперементировать... так даже с наскока не скажу :)

Кстати, а сервис твой? Ежели твой - то периодически проверяй себя на зарегеность, если кно снял, завершайся и воостанавливай себя на законное место :)


 
Ketmar ©   (2007-04-25 18:47) [4]

да так сейчас и пишу (сервис мой %-). но как-то оно не того -- помирать каждый раз. хотелось бы без смертей обойтись. %-)

мои эксперименты со всякими разными последовательностями пинков SCM результата не дали, увы. но как-то же он кэшит всё по CreateService(), например? правда, не факт, что эта машинерия общедоступна. и так неохота (да и времени нет) ковыряться там отладчиком...


 
Leonid Troyanovsky ©   (2007-04-25 22:16) [5]


> Ketmar ©   (25.04.07 18:47) [4]

Боюсь соврать, но Alex Fedotov, кажись обсуждал проблему
кеширования либо в своей статье, либо просто по форуму rsdn winapi
(А может это был Танненбаум).
Уточнять мне влом, бо скоро ФУТБОЛ!!

--
Regards, LVT.


 
Германн ©   (2007-04-26 01:41) [6]

Удалено модератором
Примечание: Offtopic


 
Сергей М. ©   (2007-04-26 10:52) [7]


> Ketmar ©   (25.04.07 18:47) [4]


Посмотри на wasm.ru статью и пример по теме "Монитор создания и уничтожения процессов" - там как раз реализована манипуляция временным созданием/уничтожением сервиса для запуска/останова драйвера режима ядра.

Вот (для облегчения анализа) Паскаль-портация ключевых фрагментов из того примера:


// старт системы слежения
procedure StartMonitor;
var
 hSCM, hService: THandle;
 idThread, BytesReturned: DWord;
 State: TServiceStatus;
begin
 if Started then Exit;
 CheckDrvFileExists; //если файла драйвера еще нет на диске в сист.каталоге ОС, создадим его из своего ресурса
 hSCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
 Win32Check(hSCM <> 0);
 try
   hService := CreateService(hSCM, "ProcessMon", "NT process Montor",
                             SERVICE_START or SERVICE_STOP or SERVICE_QUERY_STATUS or _DELETE,
                             SERVICE_KERNEL_DRIVER,
                             SERVICE_DEMAND_START,
                             SERVICE_ERROR_IGNORE,
                             PChar(DrvName),
                             nil, nil, nil, nil, nil);
   if (hService = 0) and (GetLastError = ERROR_SERVICE_EXISTS) then
     hService := OpenService(hSCM, "ProcessMon", SERVICE_ALL_ACCESS);
   Win32Check(hService <> 0);
   try
     Win32Check(QueryServiceStatus(hService, State));
     if State.dwCurrentState = SERVICE_STOPPED then
       Win32Check(StartService(hService, 0, SvcStartParams));
     with WaitParams do
     try
       hDevice := CreateFile(sDeviceName,
                             GENERIC_READ or GENERIC_WRITE,
                             0, nil, OPEN_EXISTING, 0, 0);
       Win32Check(hDevice <> 0);
       try
         hEvent := CreateEvent(nil, FALSE, FALSE, nil);
         Win32Check(hEvent <> 0);
         try
           ExitNow := False;
//стартуем следящий трэд
           hWaitThread := BeginThread(nil, 0, @WinEtkaWatchDog, @WaitParams, 0, idThread);
           Win32Check(hWaitThread <> 0);
//подождем пока трэд создаст очередь win-сообщений
           while not PostThreadMessage(idThread, WM_USER, 0, 0) do Sleep(0);
           try
//скомандуем устр-ву начать слежение за процессами
             Win32Check(DeviceIoControl(hDevice,
                                         IOCTL_SET_NOTIFY,
                                         @hEvent,
                                         SizeOf(hEvent), nil, 0, BytesReturned, nil)
                       );
             Started := True;
           except
             ExitNow := True;
             SetEvent(hEvent);
             WaitForSingleObject(hWaitThread, INFINITE);
             CloseHandle(hWaitThread);
             raise;
           end;
         except
           CloseHandle(hEvent);
           raise;
         end;
       except
         CloseHandle(hDevice);
         raise;
       end;
     except
       ControlService(hService, SERVICE_CONTROL_STOP, State);
       raise;
     end;
   finally
     DeleteService(hService);
     CloseServiceHandle(hService);
   end;
 finally
   CloseServiceHandle(hSCM);
 end;
end;

// останов системы слежения

procedure StopMonitor;
var
 hSCM, hService: THandle;
 BytesReturned: DWord;
 State: TServiceStatus;
 Success: Boolean;
begin
 if Started then
   with WaitParams do
   begin
     ExitNow := True;
     SetEvent(hEvent);
     WaitForSingleObject(hWaitThread, INFINITE);
     CloseHandle(hWaitThread);
     Win32Check(DeviceIoControl(hDevice, IOCTL_REMOVE_NOTIFY, nil, 0, nil, 0, BytesReturned, nil));
     CloseHandle(hEvent);
     CloseHandle(hDevice);
     hSCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
     hService := OpenService(hSCM, "ProcessMon", SERVICE_STOP or _DELETE);
     Success := ControlService(hService, SERVICE_CONTROL_STOP, State);
     Success := DeleteService(hService);
     CloseServiceHandle(hService);
     CloseServiceHandle(hSCM);
     Started := False;
   end;
end;


У меня под Винтукеем это работало, хотя проблема действительно имеет место быть.


 
Rouse_ ©   (2007-04-26 11:44) [8]


> Success := DeleteService(hService);

Боюсь может не пройти ибо один из задокументированных кодов возврата стоит "ERROR_SERVICE_MARKED_FOR_DELETE"


 
Сергей М. ©   (2007-04-26 12:11) [9]


> Rouse_ ©   (26.04.07 11:44) [8]


У меня под винтукеем проходило.


 
Rouse_ ©   (2007-04-26 18:04) [10]

Нет времени проверять, да и не факт что правильно, но...

SCM будет держать флаг ERROR_SERVICE_MARKED_FOR_DELETE до тех пор, пока есть открытые описатели службы. После SetServiceStatus с флагом SERRVICE_STOPPED SCM закрывает описатель службы, вот тут имеет смысл проверить - грохнет ли он твой сервис или можно будет все-таки работать дальше... Если служба не грохнется, SCM по идее должна удалить тебя из списка служб и ты сможешь провести все действия, которые нужны.


 
Rouse_ ©   (2007-04-26 18:06) [11]

Да, если получиться, то придется заново дергать RegisterServiceCtrlHandlerEx повторно, для получения нового валидного описателя службы (старый то уже будет закрыт)


 
Ketmar ©   (2007-04-27 22:12) [12]

мой сервис не держит команду "stop" (ибо нефиг %-). но дело даже не в том. процесс-то тоже могут прибить. или, например, не прибить, а просто перезагрузиться, после чего SCM грохнет запись о сервисе -- и хана.

в общем, огромный tnx за отзывы. видимо, придётся делать как думал: следилку, которая скомандует сервису помереть, если его запись пытаются удалить. и переустановит/запустит. думал обойтись "малой кровью" -- каким-то API-вызовом хитрым. увы. %-)


 
Rouse_ ©   (2007-04-27 23:49) [13]

Хм, а как ты думаешь, нафига у интербейза с фаербердом гварды написаны сервисные? :) Тоже видать малой кровью хотели обойти :)


 
Ketmar ©   (2007-04-28 12:55) [14]

если бы у гениальных архитекторов винды ещё хватило моска сделать аналог WaitForMultipleObject() для статуса сервиса... или я с устатку и не спамши не нашёл каких-то notify-функций?

потому как написать-то я написал, но глядя на разбросаные по коду Sleep()"ы хочется аффтару открутить... в общем, что-нибудь открутить. или хотя бы подёргать за. %-)


 
Rouse_ ©   (2007-05-02 12:30) [15]


> потому как написать-то я написал, но глядя на разбросаные
> по коду Sleep

А нафига? У тебя же цикл сервисный крутится? Крутиться... Вот в нем периодически и делай проверку. Слипы то нафига прикручивать?


 
clickmaker ©   (2007-05-02 12:32) [16]

Удалено модератором
Примечание: Offtopic



Страницы: 1 вся ветка

Текущий архив: 2007.11.04;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.025 c
6-1172567282
paradox01
2007-02-27 12:08
2007.11.04
Файл через сокет


15-1190800801
ТТ
2007-09-26 14:00
2007.11.04
компиляция-оптимизация


2-1192098952
Антон Шестаков
2007-10-11 14:35
2007.11.04
количество дней


2-1192086758
Quart
2007-10-11 11:12
2007.11.04
Подключение к БД


2-1192189179
Tehnik(^____^)
2007-10-12 15:39
2007.11.04
Web Browser компонент