Thursday, May 29, 2008

Delphi 7 is now compatible with Vista


Delphi 7 is now compatible with Vista, or Vista is now compatible with Delphi 7... anyway you look at it, I find this amusing.
Read it on marco's tech world.

Managing NT Services from Delphi


{-------------------------------------------------------------------------------------
Unit: uServiceManager.pas
Purpose: Wrapper around some of the Windows API Functions supporting NT-Services.
The following class TServiceManager can be used to manage your NT-Services.
You can do things like start, stop, pause or querying a services status.
Author: Kiran Kurapaty.
Copyright: Kurapaty Solutions
Dated: 18th September, 2003 at 19.10 hours IST.
Email Id: kiran@kurapaty.co.uk / kiran.delphi@gmail.com
-------------------------------------------------------------------------------------}

unit uServiceManager;

interface

uses
SysUtils, Windows, WinSvc;

type

TServiceManager = class
private
{ Private declarations }
ServiceControlManager: SC_Handle;
ServiceHandle: SC_Handle;
fServiceName: String;
protected
function DoStartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;
public
{ Public declarations }
destructor Destroy; override;
function Connect(MachineName: PChar = nil; DatabaseName: PChar = nil;
Access: DWORD = SC_MANAGER_ALL_ACCESS): Boolean; // Access may be SC_MANAGER_ALL_ACCESS
function OpenServiceConnection(aServiceName: PChar): Boolean;
function StartService: Boolean; overload; // Simple start
function StartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean; overload; // More complex start
function StopService: Boolean;
function PauseService: Boolean;
function ContinueService: Boolean;
function ShutdownService: Boolean;
function DisableService: Boolean;
function GetStatus: DWORD;
function IsServiceRunning: Boolean;
function IsServiceStopped: Boolean;
published
property ServiceName : String read fServiceName write fServiceName;
end;

implementation

{ TServiceManager }

function TServiceManager.Connect(MachineName, DatabaseName: PChar; Access: DWORD): Boolean;
begin
{ open a connection to the windows service manager }
ServiceControlManager := OpenSCManager(MachineName, DatabaseName, Access);
Result := (ServiceControlManager <> 0);
end;


function TServiceManager.OpenServiceConnection(aServiceName: PChar): Boolean;
begin
{ open a connetcion to a specific service }
fServiceName := aServiceName;
ServiceHandle := OpenService(ServiceControlManager, aServiceName, SERVICE_ALL_ACCESS);
Result := (ServiceHandle <> 0);
end;

function TServiceManager.PauseService: Boolean;
var
ServiceStatus: TServiceStatus;
begin
{ Pause the service: attention not supported by all services }
Result := ControlService(ServiceHandle, SERVICE_CONTROL_PAUSE, ServiceStatus);
end;

function TServiceManager.StopService: Boolean;
var
ServiceStatus: TServiceStatus;
begin
{ Stop the service }
Result := ControlService(ServiceHandle, SERVICE_CONTROL_STOP, ServiceStatus);
end;

function TServiceManager.ContinueService: Boolean;
var
ServiceStatus: TServiceStatus;
begin
{ Continue the service after a pause: attention not supported by all services }
Result := ControlService(ServiceHandle, SERVICE_CONTROL_CONTINUE, ServiceStatus);
end;

function TServiceManager.ShutdownService: Boolean;
var
ServiceStatus: TServiceStatus;
begin
{ Shut service down: attention not supported by all services }
Result := ControlService(ServiceHandle, SERVICE_CONTROL_SHUTDOWN, ServiceStatus);
end;

function TServiceManager.StartService: Boolean;
begin
Result := DoStartService(0, '');
end;

function TServiceManager.StartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;
begin
Result := DoStartService(NumberOfArgument, ServiceArgVectors);
end;

function TServiceManager.GetStatus: DWORD;
var
ServiceStatus: TServiceStatus;
begin
{ Returns the status of the service. Maybe you want to check this
more than once, so just call this function again.
Results may be: SERVICE_STOPPED
SERVICE_START_PENDING
SERVICE_STOP_PENDING
SERVICE_RUNNING
SERVICE_CONTINUE_PENDING
SERVICE_PAUSE_PENDING
SERVICE_PAUSED }
QueryServiceStatus(ServiceHandle, ServiceStatus);
Result := ServiceStatus.dwCurrentState;
end;

function TServiceManager.DisableService: Boolean;
begin
{ Need to Implement... }
Result := False;
end;

function TServiceManager.IsServiceRunning: Boolean;
begin
Result := (GetStatus = SERVICE_RUNNING);
end;

function TServiceManager.IsServiceStopped: Boolean;
begin
Result := (GetStatus = SERVICE_STOPPED);
end;

function TServiceManager.DoStartService(NumberOfArgument: DWORD;
ServiceArgVectors: PChar): Boolean;
begin
Result := WinSvc.StartService(ServiceHandle, NumberOfArgument, ServiceArgVectors);
end;

destructor TServiceManager.Destroy;
begin
if (ServiceHandle <> 0) then
CloseServiceHandle(ServiceHandle);
inherited;
end;

end.