Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.11.04;
Скачать: [xml.tar.bz2];

Вниз

как заставить 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 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.11.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.061 c
2-1192198988
Neo
2007-10-12 18:23
2007.11.04
как закрыть форму, если выполняется большой цикл?


3-1182932266
zz 5
2007-06-27 12:17
2007.11.04
Использование алиасов при Backup, FB1.5


15-1191550119
Slider007
2007-10-05 06:08
2007.11.04
С днем рождения ! 5 октября 2007 пятница


2-1192186547
Gurd
2007-10-12 14:55
2007.11.04
путь для db


2-1192163293
Stud
2007-10-12 08:28
2007.11.04
Где найти алгоритм перебора?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский