System Delphi

Title: Access and control a NT service
Question: The unit described in this article show how we can start or stop a NT service by programming, or getting the location of its binary implentation.
Answer:
unit SvcUtils;
// Written by Bertrand Goetzmann (http://www.object-everywhere.com)
// Keywords : Service, OpenSCManager, OpenService, CloseServiceHandle, QueryServiceConfig, StartService, QueryServiceStatus, ControlService
interface
// This function returns the entire path location of the implementation of the given name service
function GetBinaryPathName(const ServiceName: string): string;
// This function starts the service with the given service name
procedure StartService(const ServiceName: string);
// This function stops the service with the given service name
procedure StopService(const ServiceName: string);
implementation
uses SysUtils, WinSvc;
function GetBinaryPathName(const ServiceName: string): string;
var
SvcMgr, Svc: Integer;
QuerySvc: TQueryServiceConfig;
BytesNeeded: Cardinal;
Buffer: PQueryServiceConfig;
begin
// Establish a connection to the service control manager
SvcMgr := OpenSCManager(nil (*MachineName*), nil (*DatabaseName*), SC_MANAGER_ALL_ACCESS);
try
if SvcMgr = 0 then RaiseLastOSError;
Svc := OpenService(SvcMgr, PChar(ServiceName), SERVICE_ALL_ACCESS);
if Svc = 0 then RaiseLastOSError;
try
// Make a call to know the number of bytes needed
QueryServiceConfig(Svc, @QuerySvc, 0, BytesNeeded);
GetMem(Buffer, BytesNeeded);
try
if not QueryServiceConfig(Svc, Buffer, BytesNeeded, BytesNeeded) then
RaiseLastOSError;
Result := PQueryServiceConfig(Buffer).lpBinaryPathName;
finally
FreeMem(Buffer);
end;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
end;
procedure StartService(const ServiceName: string);
var
SvcMgr, Svc: Integer;
ServiceArgVectors: PChar;
begin
// Establish a connection to the service control manager
SvcMgr := OpenSCManager(nil (*MachineName*), nil (*DatabaseName*), SC_MANAGER_ALL_ACCESS);
try
if SvcMgr = 0 then RaiseLastOSError;
Svc := OpenService(SvcMgr, PChar(ServiceName), SERVICE_ALL_ACCESS);
if Svc = 0 then RaiseLastOSError;
try
if not WinSvc.StartService(Svc, 0 (*NumServiceArgs*), ServiceArgVectors) then
RaiseLastOSError;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
end;
procedure StopService(const ServiceName: string);
var
SvcMgr, Svc: Integer;
ServiceStatus: _SERVICE_STATUS;
begin
// Establish a connection to the service control manager
SvcMgr := OpenSCManager(nil (*MachineName*), nil (*DatabaseName*), SC_MANAGER_ALL_ACCESS);
try
if SvcMgr = 0 then RaiseLastOSError;
Svc := OpenService(SvcMgr, PChar(ServiceName), SERVICE_ALL_ACCESS);
if Svc = 0 then RaiseLastOSError;
try
// if not QueryServiceStatus(Svc, ServiceStatus) then
// RaiseLastOSError;
// You can test the ServiceStatus.dwCurrentState field
if not ControlService(Svc, SERVICE_CONTROL_STOP, ServiceStatus) then
RaiseLastOSError;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
end;
end.