При работе с функциями управления службами Windows в Inno Setup важно правильно обращаться с правами доступа к службам и менеджеру служб. Одна из часто встречающихся проблем заключается в использовании функции EnumDependentServices, которая предназначена для перечисления зависимых служб для заданной службы. Проблема может возникнуть при попытке вызвать эту функцию, когда возвращается код ошибки 5, что соответствует сообщению "Access Denied" (Доступ запрещён), несмотря на то, что установщик запущен от имени администратора.
Описание проблемы
Разработчик столкнулся с проблемой при попытке использовать функцию EnumDependentServices для проверки зависимых служб в Inno Setup. Несмотря на то, что установщик запускался от имени администратора, при вызове функции EnumDependentServices возвращался код ошибки 5, что указывало на отказ в доступе. Использовалось право SC_MANAGER_ALL_ACCESS для управления службами, но это не помогло разрешить проблему.
Контекст и решение проблемы
Согласно документации по функции EnumDependentServices, для вызова этой функции необходимо, чтобы уникальный идентификатор (hService) имел право SERVICE_ENUMERATE_DEPENDENTS. Это право не было указано при открытии служб, что и вызывало ошибку доступа.
Кроме того, использование SC_MANAGER_ALL_ACCESS было излишним, так как для данной операции достаточно было бы только SC_MANAGER_CONNECT.
Также в примере кода, представленном разработчиком, использовалась несуществующая константа SERVICE_CURRENT_STATUS вместо правильного значения SERVICE_STATE_ALL, которое требуется для функции EnumDependentServices.
Итоговый код
const
...
SERVICE_STATE_ALL = $0003;
SERVICE_ENUMERATE_DEPENDENTS = $0008;
ERROR_MORE_DATA = 234;
...
procedure LogError(const FuncName: string);
var
ErrCode: DWORD;
ErrMsg: string;
begin
ErrCode := GetLastError();
ErrMsg := Format('%s failed: (%d) %s', [FuncName, ErrCode, SysErrorMessage(ErrCode)]);
Log(ErrMsg);
MsgBox(ErrMsg, mbError, mb_Ok);
end;
function HasServiceDependencies(const ServiceName: string): boolean;
var
hSCM: HANDLE;
hService: HANDLE;
dwBytesNeeded: DWORD;
dwServicesReturned: DWORD;
begin
Result := False;
hSCM := OpenSCManager('', '', SC_MANAGER_CONNECT);
if hSCM = 0 then begin
LogError('OpenSCManager');
end
else begin
hService := OpenService(hSCM, ServiceName, SERVICE_ENUMERATE_DEPENDENTS);
if hService = 0 then begin
LogError('OpenService');
end
else begin
// Указываем нулевой буфер, чтобы узнать, есть ли зависимости,
// или вернётся False и установится LastError=ERROR_MORE_DATA, если
// данные о зависимостях доступны...
if EnumDependentServices(hService, SERVICE_STATE_ALL, 0, 0, dwBytesNeeded, dwServicesReturned) then begin
Log(Format('%s имеет зависимости', [ServiceName]));
end
else if GetLastError() <> ERROR_MORE_DATA then begin
LogError('EnumDependentServices');
end
else begin
Log(Format('%s имеет зависимые службы', [ServiceName]));
end;
CloseServiceHandle(hService);
end;
CloseServiceHandle(hSCM);
end;
end;
Выводы
Проверьте, что у вас есть необходимые права доступа для функции EnumDependentServices.
Используйте только те права, которые действительно необходимы для выполнения операции, не просите больше, чем нужно (например, SC_MANAGER_ALL_ACCESS вместо SC_MANAGER_CONNECT).
Убедитесь, что используемые константы соответствуют тем, что определены в документации Win32 API.
Применение этих рекомендаций поможет избежать проблем с правами доступа при использовании функции EnumDependentServices в Inno Setup.
Проблема заключается в необходимости правильного указания прав доступа при использовании функции `EnumDependentServices` в Inno Setup для избежания ошибки 'Access Denied'.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.