: How do i stop and start services in XP using delphi code, thankyou.
:
: Pyle
:
Hi,
Once wrote a component for that, it can also start/stop services on a different machine. It's very basic, but it does the trick.
unit ServiceStarter;
interface
uses
WinSvc, Windows, Messages, SysUtils, Classes;
type
TServiceState = (svsStopped, svsStarting, svsStopping, svsRunning, scvContinueing, svsPausing, svsPaused);
TServiceStarter = class(TComponent)
private
FSCHandle: THandle;
FState: TServiceState;
FServiceName: string;
FHandle: THandle;
FMachineName: string;
FActive: Boolean;
procedure SetState(const Value: TServiceState);
function GetState: TServiceState;
procedure SetServiceName(const Value: string);
procedure SetMachineName(const Value: string);
function GetHandle: THandle;
procedure SetActive(const Value: Boolean);
procedure CloseDependendServices(Handle: THandle);
{ Private declarations }
protected
{ Protected declarations }
procedure CloseHandle;
procedure CloseHandleSC;
procedure HandleNeeded;
public
{ Public declarations }
destructor Destroy; override;
property Handle: THandle read GetHandle;
published
{ Published declarations }
property ServiceName: string read FServiceName write SetServiceName;
property MachineName: string read FMachineName write SetMachineName;
property State: TServiceState read GetState write SetState;
property Active: Boolean read FActive write SetActive;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('AppGadgets', [TServiceStarter]);
end;
{ TServiceStarter }
procedure TServiceStarter.CloseHandle;
begin
if FHandle <> 0 then
begin
CloseServiceHandle(FHandle);
FHandle := 0;
end;
end;
procedure TServiceStarter.CloseHandleSC;
begin
if FSCHandle <> 0 then
begin
CloseServiceHandle(FSCHandle);
FSCHandle := 0;
end;
end;
destructor TServiceStarter.Destroy;
begin
CloseHandle;
inherited;
end;
function TServiceStarter.GetHandle: THandle;
begin
HandleNeeded;
Result := FHandle;
end;
function TServiceStarter.GetState: TServiceState;
var
ServiceStatus: TServiceStatus;
begin
if FActive then
begin
if (FServiceName = '') then
begin
Result := svsStopped;
Exit;
end;
HandleNeeded;
if not QueryServiceStatus(FHandle, ServiceStatus) then
RaiseLastOSError;
Result := TServiceState(ServiceStatus.dwCurrentState - 1);
end
else
Result := FState;
end;
procedure TServiceStarter.HandleNeeded;
begin
if FHandle = 0 then
begin
if FSCHandle = 0 then
begin
FSCHandle := OpenSCManager(Pointer(FMachineName), nil, GENERIC_EXECUTE);
if FSCHandle = 0 then
RaiseLastOSError;
end;
FHandle := OpenService(FSCHandle, PChar(FServiceName), GENERIC_EXECUTE+SERVICE_QUERY_STATUS+SERVICE_ENUMERATE_DEPENDENTS);
if FHandle = 0 then
RaiseLastOSError;
end;
end;
procedure TServiceStarter.SetActive(const Value: Boolean);
begin
if FActive = Value then
Exit;
FActive := Value;
if FActive then
State := FState
else
begin
CloseHandle;
CloseHandleSC;
end;
end;
procedure TServiceStarter.SetMachineName(const Value: string);
begin
if FMachineName = Value then
Exit;
CloseHandle;
FMachineName := Value;
end;
procedure TServiceStarter.SetServiceName(const Value: string);
begin
if FServiceName = Value then
Exit;
CloseHandle;
CloseHandleSC;
FServiceName := Value;
end;
procedure TServiceStarter.CloseDependendServices(Handle: THandle);
type
TEnumServiceStatusArray = array[0..$FFFF] of TEnumServiceStatus;
PEnumServiceStatusArray = ^TEnumServiceStatusArray;
var
Ok: boolean;
DependendHandle: THandle;
I: Integer;
ServicesCount: Cardinal;
NeededBytes: Cardinal;
DependendServices : PEnumServiceStatusArray;
ServiceStatus: TServiceStatus;
begin
NeededBytes := 1 * SizeOf(TEnumServiceStatusArray);
Ok := True;
GetMem(DependendServices, NeededBytes);
while not EnumDependentServices(Handle, SERVICE_ACTIVE, DependendServices^[0], NeededBytes, NeededBytes, ServicesCount) do
begin
if GetLastError = ERROR_MORE_DATA then
begin
FreeMem(DependendServices);
Ok:= False;
GetMem(DependendServices, NeededBytes);
end
else
RaiseLastOSError;
end;
for I := 0 to ServicesCount - 1 do
with DependendServices^[I] do
begin
DependendHandle := OpenService(FSCHandle, lpServiceName, GENERIC_EXECUTE+SERVICE_QUERY_STATUS+SERVICE_ENUMERATE_DEPENDENTS);
while not ControlService(DependendHandle, SERVICE_CONTROL_STOP, ServiceStatus) do
case GetLastError of
ERROR_DEPENDENT_SERVICES_RUNNING:
CloseDependendServices(DependendHandle);
ERROR_SERVICE_NOT_ACTIVE:
Break;
ERROR_SERVICE_CANNOT_ACCEPT_CTRL: ;
else
RaiseLastOSError;
end;
CloseServiceHandle(DependendHandle);
end;
FreeMem(DependendServices);
end;
procedure TServiceStarter.SetState(const Value: TServiceState);
const
{
SERVICE_CONTROL_STOP
Requests the service to stop. The hService handle must have SERVICE_STOP access.
SERVICE_CONTROL_PAUSE
Requests the service to pause. The hService handle must have SERVICE_PAUSE_CONTINUE access.
SERVICE_CONTROL_CONTINUE
Requests the paused service to resume. The hService handle must have SERVICE_PAUSE_CONTINUE access.
SERVICE_CONTROL_INTERROGATE
Requests the service to update immediately its current status information to the service control manager. The hService handle must have SERVICE_INTERROGATE access.
SERVICE_CONTROL_SHUTDOWN
}
StateControlMap: array[TServiceState] of Integer = (SERVICE_CONTROL_STOP, SERVICE_CONTROL_CONTINUE, SERVICE_CONTROL_STOP, SERVICE_CONTROL_CONTINUE, SERVICE_CONTROL_CONTINUE, SERVICE_CONTROL_PAUSE, SERVICE_CONTROL_PAUSE);
var
Error: Cardinal;
StateSet: boolean;
Arg: PChar;
ServiceStatus: TServiceStatus;
begin
FState := Value;
if Active then
begin
HandleNeeded;
Arg := nil;
StateSet := False;
// svsStopped, svsStarting, svsStopping, svsRunning, scvContinueing, svsPausing, svsPaused
repeat
if not ControlService(FHandle, StateControlMap[Value], ServiceStatus) then
begin
Error := GetLastError;
case Error of
ERROR_SERVICE_CANNOT_ACCEPT_CTRL:
begin
Sleep(10);
end;
ERROR_SERVICE_NOT_ACTIVE:
if not (Value in [svsStopped, svsStopping]) then
begin
if not StartService(FHandle, 0, Arg) then
begin
Error := GetLastError;
if Error <> ERROR_SERVICE_CANNOT_ACCEPT_CTRL then
RaiseLastOSError
else
Sleep(10);
end;
StateSet := Value in [svsRunning, scvContinueing];
end
else
StateSet := True;
ERROR_DEPENDENT_SERVICES_RUNNING:
CloseDependendServices(FHandle);
else
RaiseLastOSError;
end;
end
else
StateSet := True;
until StateSet;
end;
end;
end.