我正在安装服务并希望设置服务恢复选项(在XP环境中使用admin)。我可以愉快地更改描述,但如果 sfa.cActions 不是零,它会失败并显示错误 87(参数错误)。
//
// Actions to take on service failure
//
{$EXTERNALSYM _SC_ACTION_TYPE}
_SC_ACTION_TYPE = (SC_ACTION_NONE, SC_ACTION_RESTART, SC_ACTION_REBOOT, SC_ACTION_RUN_COMMAND);
{$EXTERNALSYM SC_ACTION_TYPE}
SC_ACTION_TYPE = _SC_ACTION_TYPE;
PServiceAction = ^TServiceAction;
{$EXTERNALSYM _SC_ACTION}
_SC_ACTION = record
aType : SC_ACTION_TYPE;
Delay : DWORD;
end;
{$EXTERNALSYM SC_ACTION}
SC_ACTION = _SC_ACTION;
TServiceAction = _SC_ACTION;
procedure TXyz_Service_Module.SetDescription(const Desc: ansistring);
var
hSCM: SC_HANDLE;
hService: SC_HANDLE;
sd: SERVICE_DESCRIPTION;
begin
hSCM := WinSvc.OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if hSCM = 0 then Exit;
hService := WinSvc.OpenService(hSCM, PChar(Self.Name), SERVICE_CHANGE_CONFIG);
if hService = 0 then Exit;
sd.lpDescription := PAnsiChar(Desc);
ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, @sd);
WinSvc.CloseServiceHandle(hService);
WinSvc.CloseServiceHandle(hSCM);
end;
procedure TXyz_Service_Module.SetRecovery;
var
hSCM: SC_HANDLE;
hService: SC_HANDLE;
sfa: SERVICE_FAILURE_ACTIONS;
actions: array [0 .. 2] of SC_ACTION;
begin
hSCM := WinSvc.OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if hSCM = 0 then Exit;
hService := WinSvc.OpenService(hSCM, PChar(Self.Name), SERVICE_ALL_ACCESS);
if hService = 0 then Exit;
sfa.dwResetPeriod := 999; //INFINITE;
sfa.lpCommand := nil;
sfa.lpRebootMsg := nil;
sfa.cActions := 1;
sfa.lpsaActions := @actions[0];
actions[0].aType := SC_ACTION_RESTART;
actions[0].Delay := 5000;
(*actions[1].aType := SC_ACTION_RESTART;
actions[1].Delay := 5000;
actions[2].aType := SC_ACTION_RESTART;
actions[2].Delay := 5000;*)
if not changeserviceconfig2(hservice,SERVICE_CONFIG_FAILURE_ACTIONS,@sfa) then begin
showmessage('Error : '+inttostr(getlasterror));
end;
WinSvc.CloseServiceHandle(hService);
WinSvc.CloseServiceHandle(hSCM);
end;
procedure TXyz_Service_Module.ServiceAfterInstall(Sender: TService);
begin
self.SetDescription('Bananas are yellow');
self.SetRecovery;
end;
来自ChangeServiceConfig2()
文档:
h服务 [在]
服务的句柄。此句柄由OpenService
或CreateService
函数返回,并且必须具有SERVICE_CHANGE_CONFIG
访问权限。有关详细信息,请参阅服务安全性和访问权限。如果服务控制器处理
SC_ACTION_RESTART
操作,则 hService 必须具有SERVICE_START访问权限。
因此,SetRecovery()
至少需要使用它:
hService := WinSvc.OpenService(hSCM, PChar(Self.Name), SERVICE_CHANGE_CONFIG or SERVICE_START);
枚举值。
_SC_ACTION_TYPE = (SC_ACTION_NONE, SC_ACTION_RESTART, SC_ACTION_REBOOT, SC_ACTION_RUN_COMMAND);
需要
{$MinEnumSize=4}
_SC_ACTION_TYPE = (SC_ACTION_NONE, SC_ACTION_RESTART, SC_ACTION_REBOOT, SC_ACTION_RUN_COMMAND);
正如大卫·赫弗南在评论中所建议的那样。