2011. január 10., hétfő
Access and control a NT service
Problem/Question/Abstract:
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.
FAQ:
As do to register my application as a service?
You can register your service application simply by executing it with the /INSTALL option.
How to pass multi-arguments to StartService?
You can pass some argument with the starting of a service with the call of the StartService function of the Win32 API. The StartService procedure of the SvcUtils unit makes a such call with 0 argument :
WinSvc.StartService(Svc, 0 (*NumServiceArgs*), ServiceArgVectors)
What is RaiseLastOSError?
RaiseLastOSError is a function from the SysUtils unit that permits to raise an exception for the last operating system error or library system error.
I did know how to manage this, but I'm looking for a way to have the list of all installed services. Do you have a solution for that?
I think that the EnumServicesStatus function from the Windows API is the solution.
The function enumerates services in the specified service control manager database. The name and status of each service are provided.
The code looks very nice, but one problem; what is it suposed to do?? Any insight on what this program can do to benefit us would be greatly apprecaited!
On the Windows NT plateform you can look all the installed services by executing MMC (Microsoft Managment Console). All these services can be handled by this GUI application (start, stop, suspend, etc.).
This article show the use of some of the Service Functions from the Window API to do the same things by programming
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése