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
相关产品推荐
相关产品推荐

