unit UStartStopService;
interface
uses
Windows, Classes, SysUtils;
function ServiceGetStatus(sMachine, sService :
string ) : DWord;
function ServiceStart(sMachine, sService :
string ) : boolean;
function ServiceStop(sMachine, sService :
string ) : boolean;
function ServiceRunning(sMachine, sService :
string ) : boolean;
{
// "alerter" service on \ComputerName was started take appropriate action here
if( ServiceStart('\ComputerName','alerter' ) )then begin
end;
// stop "alerter" service running on the local computer
if( ServiceStop('','alerter' ) )then begin
end;
}
function ServiceGetList(sMachine :
string; dwServiceType, dwServiceState : DWord;
slServicesList : TStrings ): boolean;
{
To get a list of all Windows services into a listbox named ListBox1:
ServiceGetList( '', SERVICE_WIN32, SERVICE_STATE_ALL, ListBox1.Items );
}
const
// Service Types
SERVICE_KERNEL_DRIVER = $00000001;
SERVICE_FILE_SYSTEM_DRIVER = $00000002;
SERVICE_ADAPTER = $00000004;
SERVICE_RECOGNIZER_DRIVER = $00000008;
SERVICE_DRIVER =
(SERVICE_KERNEL_DRIVER
or
SERVICE_FILE_SYSTEM_DRIVER
or
SERVICE_RECOGNIZER_DRIVER);
SERVICE_WIN32_OWN_PROCESS = $00000010;
SERVICE_WIN32_SHARE_PROCESS = $00000020;
SERVICE_WIN32 =
(SERVICE_WIN32_OWN_PROCESS
or
SERVICE_WIN32_SHARE_PROCESS);
SERVICE_INTERACTIVE_PROCESS = $00000100;
SERVICE_TYPE_ALL =
(SERVICE_WIN32
or
SERVICE_ADAPTER
or
SERVICE_DRIVER
or
SERVICE_INTERACTIVE_PROCESS);
implementation
uses WinSvc;
//-------------------------------------
// get service status
// return status code if successful
// 0 if not
//
// return codes:
// SERVICE_STOPPED
// SERVICE_RUNNING
// SERVICE_PAUSED
//
// following return codes
// are used to indicate that
// the service is in the
// middle of getting to one
// of the above states:
// SERVICE_START_PENDING
// SERVICE_STOP_PENDING
// SERVICE_CONTINUE_PENDING
// SERVICE_PAUSE_PENDING
//
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
//
// sService
// service name, ie: Alerter
function ServiceGetStatus(sMachine, sService :
string ) : DWord;
var
schm,
// service control manager handle
schs : SC_Handle;
// service handle
ss : TServiceStatus;
// service status
dwStat : DWord;
// current service status
begin
dwStat := 0;
// connect to the service control manager
schm := OpenSCManager( PChar(sMachine),
Nil, SC_MANAGER_CONNECT);
// if successful...
if(schm > 0)
then begin
// open a handle to the specified service
schs := OpenService( schm, PChar(sService),
SERVICE_QUERY_STATUS);
// we want to query service status
// if successful...
if(schs > 0)
then begin
// retrieve the current status of the specified service
if(QueryServiceStatus( schs, ss))
then begin
dwStat := ss.dwCurrentState;
end;
CloseServiceHandle(schs);
// close service handle
end;
CloseServiceHandle(schm);
// close service control manager handle
end;
Result := dwStat;
end;
// start service
// return TRUE if successful
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
// sService
// service name, ie: Alerter
function ServiceStart(sMachine, sService :
string ) : boolean;
var
schm,
// service control manager handle
schs : SC_Handle;
// service handle
ss : TServiceStatus;
// service status
psTemp : PChar;
// temp char pointer
dwChkP : DWord;
// check point
begin
ss.dwCurrentState := 0;
// connect to the service control manager
schm := OpenSCManager( PChar(sMachine),
Nil, SC_MANAGER_CONNECT);
// if successful...
if(schm > 0)
then begin
// open a handle to the specified service
schs := OpenService( schm, PChar(sService),
SERVICE_START
or // we want to start the service and
SERVICE_QUERY_STATUS);
// query service status
// if successful...
if(schs > 0)
then begin
psTemp :=
Nil;
if(StartService( schs, 0, psTemp))
then begin
// check status
if(QueryServiceStatus( schs, ss))
then begin
while(SERVICE_RUNNING <> ss.dwCurrentState)
do begin
// dwCheckPoint contains a value that the service
// increments periodically to report its progress
// during a lengthy operation.
dwChkP := ss.dwCheckPoint;
// save current value
// wait a bit before checking status again
// dwWaitHint is the estimated amount of time
// the calling program should wait before calling
// QueryServiceStatus() again
// idle events should be handled here...
Sleep(ss.dwWaitHint);
if(
not QueryServiceStatus( schs, ss))
then begin
break;
// couldn't check status break from the loop
end;
if(ss.dwCheckPoint < dwChkP)
then begin
// QueryServiceStatus didn't increment
// dwCheckPoint as it should have.
// avoid an infinite loop by breaking
break;
end;
end;
end;
end;
CloseServiceHandle(schs);
// close service handle
end;
// close service control manager handle
CloseServiceHandle(schm);
end;
// return TRUE if the service status is running
Result := SERVICE_RUNNING = ss.dwCurrentState;
end;
// stop service
//
// return TRUE if successful
//
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
//
// sService
// service name, ie: Alerter
//
function ServiceStop(sMachine, sService :
string ) : boolean;
var
schm,
// service control manager handle
schs : SC_Handle;
// service handle
ss : TServiceStatus;
// service status
dwChkP : DWord;
// check point
begin
// connect to the service control manager
schm := OpenSCManager(PChar(sMachine),
Nil, SC_MANAGER_CONNECT);
// if successful...
if(schm > 0)
then begin
// open a handle to the specified service
schs := OpenService( schm, PChar(sService),
SERVICE_STOP
or // we want to stop the service and
SERVICE_QUERY_STATUS);
// query service status
// if successful...
if(schs > 0)
then begin
if(ControlService( schs, SERVICE_CONTROL_STOP, ss))
then begin
// check status
if(QueryServiceStatus( schs, ss))
then begin
while(SERVICE_STOPPED <> ss.dwCurrentState)
do begin
// dwCheckPoint contains a value that the service
// increments periodically to report its progress
// during a lengthy operation.
// save current value
dwChkP := ss.dwCheckPoint;
// wait a bit before checking status again
// dwWaitHint is the estimated amount of time
// the calling program should wait before calling
// QueryServiceStatus() again
// idle events should be handled here...
Sleep(ss.dwWaitHint);
if(
not QueryServiceStatus( schs, ss))
then begin
break;
// couldn't check status break from the loop
end;
if(ss.dwCheckPoint < dwChkP)
then begin
// QueryServiceStatus didn't increment
// dwCheckPoint as it should have.
// avoid an infinite loop by breaking
break;
end;
end;
end;
end;
CloseServiceHandle(schs);
// close service handle
end;
CloseServiceHandle(schm);
// close service control manager handle
end;
// return TRUE if the service status is stopped
Result := SERVICE_STOPPED = ss.dwCurrentState;
end;
function ServiceRunning(sMachine, sService :
string ) : boolean;
begin
result := ServiceGetStatus(sMachine, sService) = SERVICE_RUNNING;
end;
// Get a list of services
// return TRUE if successful
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
// dwServiceType
// SERVICE_WIN32,
// SERVICE_DRIVER or
// SERVICE_TYPE_ALL
// dwServiceState
// SERVICE_ACTIVE,
// SERVICE_INACTIVE or
// SERVICE_STATE_ALL
// slServicesList
// TStrings variable to storage
function ServiceGetList(sMachine :
string; dwServiceType, dwServiceState : DWord;
slServicesList : TStrings ): boolean;
const
// assume that the total number of services is less than 4096.
// increase if necessary
cnMaxServices = 4096;
type
TSvcA =
array[0..cnMaxServices]
of TEnumServiceStatus;
PSvcA = ^TSvcA;
var
j : integer;
schm : SC_Handle;
// service control manager handle
nBytesNeeded,
// bytes needed for the next buffer, if any
nServices,
// number of services
nResumeHandle : DWord;
// pointer to the next unread service entry
ssa : PSvcA;
// service status array
begin
Result := false;
slServicesList.Clear;
// connect to the service control manager
schm := OpenSCManager(PChar(sMachine),
Nil, SC_MANAGER_ALL_ACCESS);
// if successful...
if(schm > 0)
then begin
nResumeHandle := 0;
New(ssa);
EnumServicesStatus( schm, dwServiceType, dwServiceState, ssa^[0],
SizeOf(ssa^), nBytesNeeded, nServices, nResumeHandle );
// assume that our initial array was large enough to hold all
// entries. add code to enumerate if necessary.
for j := 0
to nServices-1
do begin
slServicesList.Add( StrPas(ssa^[j].lpServiceName ) + '
=' + StrPas(ssa^[j].lpDisplayName ) );
end;
Result := true;
Dispose(ssa);
CloseServiceHandle(schm);
// close service control manager handle
end;
end;
end.