Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 检测windows服务状态_Delphi_Windows Services_Operating System_Delphi 2007 - Fatal编程技术网

Delphi 检测windows服务状态

Delphi 检测windows服务状态,delphi,windows-services,operating-system,delphi-2007,Delphi,Windows Services,Operating System,Delphi 2007,当然,我如何在Delphi 2007中检测Windows服务状态并更改其状态。WinSvc具有您需要的所有Windows API方法。您可以为轻松的类界面创建以下单元: unit ServiceManager; interface uses SysUtils, Windows, Winsvc; type TServiceManager = class; { The states a service can be in. } TServiceState = (ssStopp

当然,我如何在Delphi 2007中检测Windows服务状态并更改其状态。

WinSvc具有您需要的所有Windows API方法。您可以为轻松的类界面创建以下单元:

unit ServiceManager;

interface

uses
  SysUtils, Windows, Winsvc;

type
  TServiceManager = class;

  { The states a service can be in. }
  TServiceState = (ssStopped,
                   ssStartPending,
                   ssStopPending,
                   ssRunning,
                   ssContinuePending,
                   ssPausePending,
                   ssPaused);

  { Enumeration of the standard "controls" a service can accept. The shutdown control, if not
    accepted is ignored. The shutdown control can only be sent when a shutdown occurs. }
  TServiceAccept = (saStop,
                    saPauseContinue,
                    saShutdown);

  { The set of "controls" a service can accept. }
  TServiceAccepts = set of TServiceAccept;

  { The service startup enumeration determines how a service is started. ssAutomatic will start the
    service automatically at startup. ssManual will allow applications and other services to start
    this service manually and ssDisabled will disallow the service to be started altogether (but it
    will be kept in the service database). }
  TServiceStartup = (ssAutomatic,
                     ssManual,
                     ssDisabled);

  { Gives information of and controls a single Service. Can be accessed via @link(TServiceManager). }
  TServiceInfo = class
  private
    { Placeholder of the Index property.  Assigned by the ServiceManager that created this instance. }
    FIndex: Integer;
    { Link the the creating service manager. }
    FServiceManager: TServiceManager;
    { Handle of the service during several member calls. }
    FHandle: SC_HANDLE;
    { Status of thi service. This contains several fields for several properties. }
    FServiceStatus: TServiceStatus;
    { Key name of this service. }
    FServiceName: string;
    { Display name oif this service. }
    FDisplayName: string;
    { Are de depenedents searched. If so the @link(FDependents) array is filled with those. }
    FDependentsSearched: Boolean;
    { Array of @link(TServiceInfo) instances that depent on this service. Only filled when
      @link(FDependentsSearched) is True. }
    FDependents: array of TServiceInfo;
    { Placeholder for the live}
    FLive: Boolean;
    // Query Config
    FConfigQueried: Boolean;
    FOwnProcess: Boolean;
    FInteractive: Boolean;
    FStartType: TServiceStartup;
    FBinaryPath: string;
    FUserName: string;
    function GetDependent(Index: Integer): TServiceInfo;
    function GetDepenentCount: Integer;
    function GetState: TServiceState;
    function GetOwnProcess: Boolean;
    function GetInteractive: Boolean;
    function GetStartType: TServiceStartup;
    function GetBinaryPath: string;
    procedure SetState(const Value: TServiceState);
    function GetServiceAccept: TServiceAccepts;
    procedure SetStartType(const Value: TServiceStartup);
  protected
    { Cleanup the handle created with @link(GetHandle). }
    procedure CleanupHandle;
    { Open a handle to the service with the given access rights.
      This handle can be deleted via @link(CleanupHandle). }
    procedure GetHandle(Access: DWORD);
    { Query all dependent services (list them via the @link(TServiceManager). }
    procedure SearchDependants;
    { Query the current status of this service }
    procedure Query;
    { Wait for a given status of this service... }
    procedure WaitFor(State: DWORD);
    { Fetch the configuration information }
    procedure QueryConfig;
  public
    constructor Create;
    destructor Destroy; override;
    { Action: Pause a running service. }
    procedure ServicePause(Wait: Boolean);
    { Action: Continue a paused service. }
    procedure ServiceContinue(Wait: Boolean);
    { Action: Stop a running service. }
    procedure ServiceStop(Wait: Boolean);
    { Action: Start a not running service.
      You can use the @link(State) property to change the state from ssStopped to ssRunning }
    procedure ServiceStart(Wait: Boolean);
    { Name of this service. }
    property ServiceName: string read FServiceName;
    { Display name of this service }
    property DisplayName: string read FDisplayName;
    { Number of dependant services of this service }
    property DependentCount: Integer read GetDepenentCount;
    { Access to serviced that depent on this service }
    property Dependents[Index: Integer]: TServiceInfo read GetDependent;
    { The current state of the service. You can set the service only to the non-transitional states.
      You can restart the service by first setting the State to first ssStopped and second ssRunning. }
    property State: TServiceState read GetState write SetState;
    { Are various properties using live information or historic information. }
    property Live: Boolean read FLive write FLive;
    { When service is running, does it run as a separate process (own process) or combined with
      other services under svchost. }
    property OwnProcess: Boolean read GetOwnProcess;
    { Is the service capable of interacting with the desktop.
      Possible: The logon must the Local System Account. }
    property Interactive: Boolean read GetInteractive;
    { How is this service started. See @link(TServiceStartup) for a description of startup types.
      If you want to set this property, the manager must be activeted with AllowLocking set to True. }
    property StartType: TServiceStartup read GetStartType write SetStartType;
    { Path to the binary that implements the service. }
    property BinaryPath: string read GetBinaryPath;
    { See what controls the service accepts. }
    property Accepts: TServiceAccepts read GetServiceAccept;
    { Index in ServiceManagers list }
    property Index: Integer read FIndex;
  end;

  { A service manager allows the services of a particular machine to be explored and modified. }
  TServiceManager = class
  private
    FManager: SC_HANDLE;
    FLock: SC_LOCK;
    FMachineName: string;
    FServices: array of TServiceInfo;
    FAllowLocking: Boolean;
    function GetActive: Boolean;
    procedure SetActive(const Value: Boolean);
    procedure SetMachineName(const Value: string);
    function GetServiceCount: Integer;
    function GetService(Index: Integer): TServiceInfo;
    function GetServiceByName(Name: string): TServiceInfo;
    procedure SetAllowLocking(const Value: Boolean);
  protected
    { Internal function that frees up all the @link(TServiceInfo) classes. }
    procedure CleanupServices;
    { Internal function for locking the manager }
    procedure Lock;
    { Internal function for unlocking the manager }
    procedure Unlock;
  public
    constructor Create;
    destructor Destroy; override;
    { Requeries the states, names etc of all services on the given @link(MachineName).
      Works only while active. }
    procedure RebuildServicesList;
    { Delete a service... }
    procedure DeleteService(Index: Integer);
    { Get the number of services. This number is refreshed when the @link(Active) is
      set to True or @link(RebuildServicesList) is called. Works only while active. }
    property ServiceCount: Integer read GetServiceCount;
    { Find a servce by index in the services list. This list is refreshed when the @link(Active) is
      set to True or @link(RebuildServicesList) is called. Works only while active. Valid Index
      values are 0..@link(ServiceCount) - 1. }
    property Services[Index: Integer]: TServiceInfo read GetService;
    { Find services by name (case insensitive). Works only while active. If no service can be found
      an exception will be raised. }
    property ServiceByName[Name: string]: TServiceInfo read GetServiceByName;
//  published
    { Activate / deactivate the service managaer. In active state can you access the individual
      service }
    property Active: Boolean read GetActive write SetActive;
    { The machine name for which you want the services list. }
    property MachineName: string read FMachineName write SetMachineName;
    { Allow locking... Is needed only when changing several properties in TServiceInfo.
      Property can only be set while inactive. }
    property AllowLocking: Boolean read FAllowLocking write SetAllowLocking;
  end;

implementation

{ TServiceManager }

procedure TServiceManager.RebuildServicesList;
var
  Services, S: PEnumServiceStatus;
  BytesNeeded,ServicesReturned,ResumeHandle: DWORD;
  i: Integer;
begin
  if not Active then raise Exception.Create('BuildServicesList only works when active');
  // Cleanup
  CleanupServices;
  // Get the amount of memory we need...
  ServicesReturned := 0;
  ResumeHandle := 0;
  Services := nil;
  if EnumServicesStatus(FManager, SERVICE_WIN32, SERVICE_ACTIVE or SERVICE_INACTIVE,
                     Services^,0, BytesNeeded,ServicesReturned,ResumeHandle) then Exit;
  if GetLastError <> ERROR_MORE_DATA then RaiseLastOSError;
  // And... Get all the data...
  GetMem(Services,BytesNeeded);
  try
    ServicesReturned := 0;
    ResumeHandle := 0;
    S := Services;
    if not EnumServicesStatus(FManager, SERVICE_WIN32, SERVICE_ACTIVE or SERVICE_INACTIVE,
                       Services^,BytesNeeded, BytesNeeded,ServicesReturned,ResumeHandle) then Exit;
    SetLength(FServices,ServicesReturned);
    for i := 0 to ServicesReturned - 1 do begin
      FServices[i] := TServiceInfo.Create;
      FServices[i].FServiceName := S^.lpServiceName;
      FServices[i].FDisplayName := S^.lpDisplayName;
      FServices[i].FServiceStatus := S^.ServiceStatus;
      FServices[i].FServiceManager := Self;
      FServices[i].FIndex := i;
      Inc(S);
    end;
  finally
    FreeMem(Services);
  end;
end;

procedure TServiceManager.CleanupServices;
var
  i: Integer;
begin
  for i := 0 to High(FServices) do FServices[i].Free;
  SetLength(FServices,0);
end;

constructor TServiceManager.Create;
begin
  inherited Create;
  FManager := 0;
end;

destructor TServiceManager.Destroy;
begin
  Active := False;
  inherited Destroy;
end;

function TServiceManager.GetActive: Boolean;
begin
  Result := FManager <> 0;
end;

function TServiceManager.GetService(Index: Integer): TServiceInfo;
begin
  // Sanity check
  if (Index < 0) or (Index >= Length(FServices)) then raise Exception.Create('Index out of bounds');
  // Fetch the object of interest
  Result := FServices[Index];
end;

function TServiceManager.GetServiceByName(Name: string): TServiceInfo;
var
  i: Integer;
begin
  Name := Uppercase(Name);
  for i := 0 to High(FServices) do begin
    Result := FServices[i];
    if Uppercase(Result.ServiceName) = Name then Exit;
  end;
  raise Exception.Create('Service not found');
end;

function TServiceManager.GetServiceCount: Integer;
begin
  Result := Length(FServices);
end;

procedure TServiceManager.SetActive(const Value: Boolean);
var
  VersionInfo: TOSVersionInfo;
  DesiredAccess: DWORD;
begin
  if Value then begin
    if FManager <> 0 then Exit;
    // Check that we are NT, 2000, XP or above...
    VersionInfo.dwOSVersionInfoSize := sizeof(VersionInfo);
    if not Windows.GetVersionEx(VersionInfo) then RaiseLastOSError;
    if VersionInfo.dwPlatformId <> VER_PLATFORM_WIN32_NT    then begin
      raise Exception.Create('This program only works on Windows NT, 2000 or XP');
    end;
    // Open service manager
    DesiredAccess := SC_MANAGER_CONNECT or SC_MANAGER_ENUMERATE_SERVICE;
    if FAllowLocking then Inc(DesiredAccess,SC_MANAGER_LOCK);
    FManager := OpenSCManager(PChar(FMachineName),nil,DesiredAccess);
    if FManager = 0 then RaiseLastOSError;
    // Fetch the srvices list
    RebuildServicesList;
  end else begin
    if FManager = 0 then Exit;
    // CleanupServices
    CleanupServices;
    // Close service manager
    if Assigned(FLock) then Unlock;
    CloseServiceHandle(FManager);
    FManager := 0;
  end;
end;

procedure TServiceManager.SetMachineName(const Value: string);
begin
  if Active then raise Exception.Create('Cannot change machine name while active');
  FMachineName := Value;
end;

procedure TServiceManager.DeleteService(Index: Integer);
begin
  // todo: implementation
  raise Exception.Create('Not implemented');
end;

procedure TServiceManager.Lock;
begin
  if not FAllowLocking then raise Exception.Create('Locking of the service manager not allowed!');
  FLock := LockServiceDatabase(FManager);
  if FLock = nil then RaiseLastOSError;
end;

procedure TServiceManager.Unlock;
begin
  // We are unlocked already
  if FLock = nil then Exit;
  // Unlock...
  if not UnlockServiceDatabase(FLock) then RaiseLastOSError;
  FLock := nil;
end;

procedure TServiceManager.SetAllowLocking(const Value: Boolean);
begin
  if Active then raise Exception.Create('Cannot change allow locking while active');
  FAllowLocking := Value;
end;

{ TServiceInfo }

procedure TServiceInfo.CleanupHandle;
begin
  if FHandle = 0 then Exit;
  CloseServiceHandle(FHandle);
  FHandle := 0;
end;

constructor TServiceInfo.Create;
begin
  FDependentsSearched := False;
  FConfigQueried := False;
  FHandle := 0;
  FLive := False;
end;

destructor TServiceInfo.Destroy;
begin
  CleanupHandle;
  inherited Destroy;
end;

function TServiceInfo.GetDependent(Index: Integer): TServiceInfo;
begin
  SearchDependants;
  if (Index < 0) or (Index >= Length(FDependents)) then raise Exception.Create('Index out of bounds');
  Result := FDependents[Index];
end;

function TServiceInfo.GetDepenentCount: Integer;
begin
  SearchDependants;
  Result := Length(FDependents);
end;

procedure TServiceInfo.GetHandle(Access: DWORD);
begin
  if FHandle <> 0 then Exit;
  FHandle := OpenService(FServiceManager.FManager,PChar(FServiceName),Access);
  if FHandle = 0 then RaiseLastOSError;
end;

function TServiceInfo.GetState: TServiceState;
begin
  if FLive then Query;
  case FServiceStatus.dwCurrentState of
    SERVICE_STOPPED:          Result := ssStopped;
    SERVICE_START_PENDING:    Result := ssStartPending;
    SERVICE_STOP_PENDING:     Result := ssStopPending;
    SERVICE_RUNNING:          Result := ssRunning;
    SERVICE_CONTINUE_PENDING: Result := ssContinuePending;
    SERVICE_PAUSE_PENDING:    Result := ssPausePending;
    SERVICE_PAUSED:           Result := ssPaused;
    else                      raise Exception.Create('Service State unknown');
  end;
end;

procedure TServiceInfo.Query;
var
  Status: TServiceStatus;
begin
  if FHandle <> 0 then begin
    if not QueryServiceStatus(FHandle,Status) then RaiseLastOSError;
  end else begin
    GetHandle(SERVICE_QUERY_STATUS);
    try
      if not QueryServiceStatus(FHandle,Status) then RaiseLastOSError;
    finally
      CleanupHandle;
    end;
  end;
  FServiceStatus := Status;
end;

procedure TServiceInfo.ServiceContinue(Wait: Boolean);
var
  Status: TServiceStatus;
begin
  GetHandle(SERVICE_QUERY_STATUS or SERVICE_PAUSE_CONTINUE);
  try
    if not (saPauseContinue in Accepts) then raise Exception.Create('Service cannot be continued');
    if not ControlService(FHandle,SERVICE_CONTROL_CONTINUE,Status) then RaiseLastOSError;
    if Wait then WaitFor(SERVICE_RUNNING);
  finally
    CleanupHandle;
  end;
end;

procedure TServiceInfo.ServicePause(Wait: Boolean);
var
  Status: TServiceStatus;
begin
  GetHandle(SERVICE_QUERY_STATUS or SERVICE_PAUSE_CONTINUE);
  try
    if not (saPauseContinue in Accepts) then raise Exception.Create('Service cannot be paused');
    if not ControlService(FHandle,SERVICE_CONTROL_PAUSE,Status) then RaiseLastOSError;
    if Wait then WaitFor(SERVICE_PAUSED);
  finally
    CleanupHandle;
  end;
end;

procedure TServiceInfo.ServiceStart(Wait: Boolean);
var
  P: PCHar;
begin
  GetHandle(SERVICE_QUERY_STATUS or SERVICE_START);
  try
    P := nil;
    if not StartService(FHandle,0,P) then RaiseLastOSError;
    if Wait then WaitFor(SERVICE_RUNNING);
  finally
    CleanupHandle;
  end;
end;

procedure TServiceInfo.ServiceStop(Wait: Boolean);
var
  Status: TServiceStatus;
begin
  GetHandle(SERVICE_QUERY_STATUS or SERVICE_STOP);
  try
    if not (saStop in Accepts) then raise Exception.Create('Service cannot be Stopped');
    if not ControlService(FHandle,SERVICE_CONTROL_STOP,Status) then RaiseLastOSError;
    if Wait then WaitFor(SERVICE_STOPPED);
  finally
    CleanupHandle;
  end;
end;

procedure TServiceInfo.WaitFor(State: DWORD);
var
  OldCheckPoint, Wait: DWORD;
begin
  Query;
  while State <> FServiceStatus.dwCurrentState do begin
    OldCheckPoint := FServiceStatus.dwCheckPoint;
    Wait := FServiceStatus.dwWaitHint;
    if Wait <= 0 then Wait := 5000;
    Sleep(Wait);
    Query;
    if State = FServiceStatus.dwCurrentState then Break;
    if FServiceStatus.dwCheckPoint <> OldCheckPoint then begin
      raise Exception.Create('Service did not react within timeframe given');
    end;
  end;
end;

procedure TServiceInfo.SearchDependants;
var
  Services, S: PEnumServiceStatus;
  BytesNeeded, ServicesReturned: DWORD;
  i: Integer;
begin
  if FDependentsSearched then Exit;
  // No dependants found...
  SetLength(FDependents,0);
  // We need a handle to the service to do any good...
  GetHandle(SERVICE_ENUMERATE_DEPENDENTS);
  try
    // See how many dependantw we have...
    Services := nil;
    BytesNeeded := 0;
    ServicesReturned := 0;
    if EnumDependentServices(FHandle,SERVICE_ACTIVE + SERVICE_INACTIVE, Services^,
                          0, BytesNeeded, ServicesReturned) then Exit;
    if GetLastError <> ERROR_MORE_DATA then RaiseLastOSError;
    // Allocate the buffer needed and fetch all info...
    GetMem(Services,BytesNeeded);
    try
      if not EnumDependentServices(FHandle,SERVICE_ACTIVE + SERVICE_INACTIVE, Services^,
                          BytesNeeded, BytesNeeded, ServicesReturned) then RaiseLastOSError;
      // Now process it...
      S := Services;
      SetLength(FDependents,ServicesReturned);
      for i := 0 to High(FDependents) do begin
        FDependents[i] := FServiceManager.ServiceByName[S^.lpServiceName];
        Inc(S);
      end;
    finally
      FreeMem(Services);
    end;
  finally
    CleanupHandle;
  end;
  FDependentsSearched := True;
end;

procedure TServiceInfo.QueryConfig;
var
  Buffer: PQueryServiceConfig;
  BytesNeeded: DWORD;
begin
  GetHandle(SERVICE_QUERY_CONFIG);
  try
    // See how large our buffer must be...
    Buffer := nil;
    assert(QueryServiceConfig(FHandle,Buffer,0,BytesNeeded) = False);
    if GetLastError <> ERROR_INSUFFICIENT_BUFFER then RaiseLastOSError;
    GetMem(Buffer,BytesNeeded);
    try
      // Perform the query...
      if not QueryServiceConfig(FHandle,Buffer,BytesNeeded,BytesNeeded) then RaiseLastOSError;
      // Analyse the query...
      assert(Buffer^.dwServiceType and SERVICE_WIN32 <> 0); // It must be a WIN32 service
      FOwnProcess := (Buffer^.dwServiceType and SERVICE_WIN32) = SERVICE_WIN32_OWN_PROCESS;
      FInteractive := (Buffer^.dwServiceType and SERVICE_INTERACTIVE_PROCESS) = SERVICE_INTERACTIVE_PROCESS;
      case Buffer^.dwStartType of
        SERVICE_AUTO_START:    FStartType := ssAutomatic;
        SERVICE_DEMAND_START:  FStartType := ssManual;
        SERVICE_DISABLED:      FStartType := ssDisabled;
        else                   raise Exception.Create('Service Start Type unknown');
      end;
      FBinaryPath := Buffer^.lpBinaryPathName;
      FUsername := Buffer^.lpServiceStartName;
      FConfigQueried := True;
    finally
      FreeMem(Buffer);
    end;
  finally
    CleanupHandle;
  end;
end;

function TServiceInfo.GetOwnProcess: Boolean;
begin
  if FLive or not FConfigQueried then QueryConfig;
  Result := FOwnProcess;
end;

function TServiceInfo.GetInteractive: Boolean;
begin
  if FLive or not FConfigQueried then QueryConfig;
  Result := FInteractive;
end;

function TServiceInfo.GetStartType: TServiceStartup;
begin
  if FLive or not FConfigQueried then QueryConfig;
  Result := FStartType;
end;

function TServiceInfo.GetBinaryPath: string;
begin
  if FLive or not FConfigQueried then QueryConfig;
  Result := FBinaryPath;
end;

function TServiceInfo.GetServiceAccept: TServiceAccepts;
begin
  Result := [];
  if FLive then Query;
  if FServiceStatus.dwControlsAccepted and SERVICE_ACCEPT_PAUSE_CONTINUE <> 0 then Result := Result + [saPauseContinue];
  if FServiceStatus.dwControlsAccepted and SERVICE_ACCEPT_STOP <> 0 then Result := Result + [saStop];
  if FServiceStatus.dwControlsAccepted and SERVICE_ACCEPT_SHUTDOWN <> 0 then Result := Result + [saShutdown];
end;



procedure TServiceInfo.SetState(const Value: TServiceState);
var
  OldState: TServiceState;
begin
  // Make sure we have the latest current state and that it is not a transitional state.
  if not FLive then Query;
  OldState := GetState;
  case OldState of
    ssStartPending:    WaitFor(SERVICE_RUNNING);
    ssStopPending:     WaitFor(SERVICE_STOPPED);
    ssContinuePending: WaitFor(SERVICE_RUNNING);
    ssPausePending:    WaitFor(SERVICE_PAUSED);
  end;
  OldState := GetState;
  // See what we need to do...
  case Value of
    ssStopped: if OldState <> ssStopped then ServiceStop(True);
    ssRunning: case OldState of
                 ssStopped: ServiceStart(True);
                 ssPaused:  ServiceContinue(True);
               end;
    ssPaused:  case OldState of
                 ssStopped: begin
                              ServiceStart(True);
                              try
                                ServicePause(True); // some services do not support pause/continue!
                              except
                                ServiceStop(True);
                                raise;
                              end;
                            end;
                 ssRunning: ServicePause(True);
               end;
    else       raise Exception.Create('Cannot set a transitional state in TServiceInfo.');
  end;
end;


procedure TServiceInfo.SetStartType(const Value: TServiceStartup);
const
  NewStartTypes: array [TServiceStartup] of DWORD =
    (SERVICE_AUTO_START, SERVICE_DEMAND_START, SERVICE_DISABLED);
begin
  // Check if it is not a change?
  QueryConfig;
  if Value = FStartType then Exit;
  // Alter it...
  FServiceManager.Lock;
  try
    GetHandle(SERVICE_CHANGE_CONFIG);
    try
      // We locked the manager and are allowed to change the configuration...
      if not ChangeServiceConfig(FHandle,SERVICE_NO_CHANGE,NewStartTypes[Value],SERVICE_NO_CHANGE,
                                 nil,nil,nil,nil,nil,nil,nil) then RaiseLastOSError;
      // well... we changed it, mark as such
      FStartType := Value;
    finally
      CleanupHandle;
    end;
  finally
    FServiceManager.Unlock;
  end;
end;

end.
单位服务经理;
接口
使用
SysUtils、Windows、Winsvc;
类型
TServiceManager=class;
{服务可以处于的状态。}
TServiceState=(ssStopped,
ssStartPending,
结束时,
ssRunning,
继续,
ssPausePending,
(暂停);
{服务可以接受的标准“控件”的枚举。如果不是,则关闭控件
已接受被忽略。只有在发生关机时才能发送关机控件。}
TServiceAccept=(saStop,
saPauseContinue,
萨休顿);
{服务可以接受的“控件”集。}
TServiceAccept=TServiceAccept的集合;
{服务启动枚举确定如何启动服务。ssAutomatic将启动
服务在启动时自动启动。ssManual将允许应用程序和其他服务启动
此服务手动和ssDisabled将不允许完全启动该服务(但
将保留在服务数据库中。)}
TServiceStartup=(ssAutomatic,
ssManual,
(残疾人士);
{提供单个服务的信息并控制该服务。可通过@link(TServiceManager)访问。}
TServiceInfo=class
私有的
{索引属性的占位符。由创建此实例的ServiceManager分配。}
FIndex:整数;
{链接到创建服务管理器。}
FServiceManager:TServiceManager;
{在几个成员调用期间处理服务。}
手柄:SC_手柄;
{该服务的状态。它包含多个属性的多个字段。}
FServiceStatus:TServiceStatus;
{此服务的密钥名。}
FServiceName:字符串;
{显示此服务的名称。}
FDisplayName:字符串;
{是否搜索了反依赖项。如果是,则@link(FDependents)数组将填充这些项。}
fdependentssearch:布尔值;
{依赖于此服务的@link(TServiceInfo)实例数组。仅在
@链接(fdependentssearch)为True。}
FDependents:TServiceInfo的数组;
{活动的占位符}
FLive:布尔;
//查询配置
FConfigQuery:布尔型;
FOwnProcess:布尔;
FInteractive:布尔型;
FStartType:TServiceStartup;
FBinaryPath:字符串;
FUserName:字符串;
函数GetDependent(索引:整数):TServiceInfo;
函数getDependentCount:整数;
函数GetState:TServiceState;
函数GetOwnProcess:Boolean;
函数GetInteractive:Boolean;
函数GetStartType:TServiceStartup;
函数GetBinaryPath:string;
程序设置状态(常量值:TServiceState);
函数GetServiceAccept:TServiceAccepts;
程序SetStartType(常量值:TServiceStartup);
受保护的
{清理用@link(GetHandle)创建的句柄。}
程序清理手柄;
{打开具有给定访问权限的服务句柄。
可以通过@link(CleanupHandle)删除此句柄。}
程序GetHandle(访问:DWORD);
{查询所有依赖服务(通过@link(TServiceManager)列出它们)。}
受抚养人的程序;
{查询此服务的当前状态}
程序查询;
{等待此服务的给定状态…}
等待程序(州:DWORD);
{获取配置信息}
程序查询配置;
公众的
构造函数创建;
析构函数销毁;重写;
{操作:暂停正在运行的服务。}
过程ServicePause(等待:布尔值);
{操作:继续暂停的服务。}
过程ServiceContinue(等待:布尔值);
{操作:停止正在运行的服务。}
过程服务停止(等待:布尔值);
{操作:启动未运行的服务。
您可以使用@link(State)属性将状态从ssStopped更改为ssRunning}
过程ServiceStart(等待:布尔值);
{此服务的名称。}
属性ServiceName:字符串读取FServiceName;
{显示此服务的名称}
属性DisplayName:字符串读取FDisplayName;
{此服务的从属服务数}
属性DependentCount:整数读取GetDependentCount;
{访问依赖于此服务的服务对象}
属性依赖项[索引:整数]:TServiceInfo读取GetDependent;
{服务的当前状态。您只能将服务设置为非过渡状态。
您可以通过首先将状态设置为first ssStopped和second ssRunning来重新启动服务。}
属性状态:TServiceState读取GetState写入SetState;
{是使用实时信息或历史信息的各种属性。}
属性Live:布尔读片写片;
{当服务运行时,它是作为单独的进程(自己的进程)运行还是与
svchost下的其他服务。}
属性OwnProcess:布尔读取GetOwnProcess;
{是能够与桌面交互的服务。
可能:登录必须是本地系统帐户。}
属性交互:布尔读取GetInteractive;
{此服务是如何启动的。有关启动类型的说明,请参阅@link(TServiceStartup)。
如果要设置此属性,必须在AllowLocking设置为True的情况下激活管理器。}
属性StartType:TServiceStartup读取GetStartType写入SetStartType;
{实现服务的二进制文件的路径。}
属性BinaryPath:字符串读取GetBinaryPath;
{查看服务接受的控件。}
属性接受:TServiceAccepts读取GetServiceAccept;
{ServiceManager列表中的索引}
属性索引:整数读取FIndex;
结束;
{服务管理器允许PAR服务