You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Inno Setup调用EnumDependentServices遇错误码5(拒绝访问)问题

问题:Inno Setup调用EnumDependentServices返回错误码5(拒绝访问)

我正在开发Inno Setup安装程序,需要检查指定服务的依赖服务。根据MSDN文档,应使用EnumDependentServices()函数,但以管理员身份运行安装程序时,调用该函数返回错误码5(表示“拒绝访问”)。我使用SC_MANAGER_ALL_ACCESS (0xF003F)权限打开服务控制管理器句柄,SCManager和打开的测试服务(DnsCache)均返回非零值,且能正常配合其他函数使用。尝试修改状态和查询代码后,问题仍未解决。以下是.iss文件的[Code]代码片段:

#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif

type
    SERVICE_STATUS = record
    dwServiceType: DWORD;
    dwCurrentState: DWORD;
    dwControlsAccepted: DWORD;
    dwWin32ExitCode: DWORD;
    dwServiceSpecificExitCode: DWORD;
    dwCheckPoint: DWORD;
    dwWaitHint: DWORD;
  end;
    HANDLE = THandle;
    PDWord = DWORD;

const
    SERVICE_QUERY_CONFIG        = $1;
    SC_MANAGER_CONNECT          = $0001;
    SERVICE_QUERY_STATUS        = $0004;
    SERVICE_CHANGE_CONFIG       = $2;
    SERVICE_CURRENT_STATUS      = $0003;
    SERVICE_START               = $10;
    SERVICE_STOP                = $20;
    SERVICE_ALL_ACCESS          = $f01ff;
    SC_MANAGER_ALL_ACCESS       = $F003F;
    SERVICE_WIN32_OWN_PROCESS   = $10;
    SERVICE_WIN32_SHARE_PROCESS = $20;
    SERVICE_WIN32               = $30;
    SERVICE_INTERACTIVE_PROCESS = $100;
    SERVICE_BOOT_START          = $0;
    SERVICE_SYSTEM_START        = $1;
    SERVICE_AUTO_START          = $2;
    SERVICE_DEMAND_START        = $3;
    SERVICE_DISABLED            = $4;
    SERVICE_DELETE              = $10000;
    SERVICE_CONTROL_STOP        = $1;
    SERVICE_CONTROL_PAUSE       = $2;
    SERVICE_CONTROL_CONTINUE    = $3;
    SERVICE_CONTROL_INTERROGATE = $4;
    SERVICE_STOPPED             = $1;
    SERVICE_START_PENDING       = $2;
    SERVICE_STOP_PENDING        = $3;
    SERVICE_RUNNING             = $4;
    SERVICE_CONTINUE_PENDING    = $5;
    SERVICE_PAUSE_PENDING       = $6;
    SERVICE_PAUSED              = $7;

// #######################################################################################
// nt based service utilities
// #######################################################################################
function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE;
external 'OpenSCManager{#AW}@advapi32.dll stdcall';

function OpenService(hSCManager :HANDLE;lpServiceName: string; dwDesiredAccess :cardinal): HANDLE;
external 'OpenService{#AW}@advapi32.dll stdcall';

function CloseServiceHandle(hSCObject :HANDLE): boolean;
external 'CloseServiceHandle@advapi32.dll stdcall';

function CreateService(hSCManager :HANDLE;lpServiceName, lpDisplayName: string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl: cardinal;lpBinaryPathName,lpLoadOrderGroup: String; lpdwTagId : cardinal;lpDependencies,lpServiceStartName,lpPassword :string): cardinal;
external 'CreateService{#AW}@advapi32.dll stdcall';

function DeleteService(hService :HANDLE): boolean;
external 'DeleteService@advapi32.dll stdcall';

function StartNTService(hService :HANDLE;dwNumServiceArgs : cardinal;lpServiceArgVectors : cardinal) : boolean;
external 'StartService{#AW}@advapi32.dll stdcall';

function ControlService(hService :HANDLE; dwControl :cardinal;var ServiceStatus :SERVICE_STATUS) : boolean;
external 'ControlService@advapi32.dll stdcall';

function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean;
external 'QueryServiceStatus@advapi32.dll stdcall';

function QueryServiceStatusEx(hService :HANDLE;ServiceStatus :SERVICE_STATUS) : boolean;
external 'QueryServiceStatus@advapi32.dll stdcall';

function GetLastError() : cardinal;
external 'GetLastError@kernel32.dll stdcall';

function EnumDependentServices(
  hService :HANDLE; 
  ServiceStatus : LongInt; 
  lpServices: DWORD; 
  cbBufSize: DWORD; 
  var pcbBytesNeeded: DWORD; 
  var lpServicesReturned : DWORD) : boolean;
external 'EnumDependentServices{#AW}@advapi32.dll stdcall';

function HasServiceDependencies(const ServiceName: string) : boolean;
var  
  hSCM: HANDLE;
  hService: HANDLE;
  pcbBytesNeeded : DWORD;
  lpServicesReturned : DWORD;
begin
    hSCM := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);
    Log(Format('%d', [hSCM]));
    if hSCM <> 0 then begin
        hService := OpenService(hSCM, ServiceName, SERVICE_QUERY_STATUS);
        Log(Format('%d', [hService]));
        if hService <> 0 then begin

            EnumDependentServices( hService, SERVICE_CURRENT_STATUS, 0, 0, pcbBytesNeeded, lpServicesReturned);
            
            MsgBox(SysErrorMessage(DLLGetLastError()), mbError, mb_Ok);

            CloseServiceHandle(hService)
            end;
        CloseServiceHandle(hSCM)
    end;
    Result := false;
end;

function InitializeSetup(): Boolean;
begin
  Log('InitializeSetup called');
  Result := HasServiceDependencies('Dnscache');
  if Result = False then
    MsgBox('InitializeSetup:' #13#13 'Ok, bye bye.', mbInformation, MB_OK);
end;

内容的提问来源于stack exchange,提问作者Michael Scholl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:05:42