使用更改服务配置2设置恢复选项的权限时出错



我正在安装服务并希望设置服务恢复选项(在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服务 [在]
服务的句柄。此句柄由 OpenServiceCreateService 函数返回,并且必须具有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);

正如大卫·赫弗南在评论中所建议的那样。

最新更新