Access and control a NT service (Views: 31)
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 |