Форум: "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.51 MB
Время: 0.044 c