中国开发网: 论坛: 程序员情感CBD: 贴子 184161
pcplayer: unit ServiceManager
unit ServiceManager;

interface

uses
SysUtils, Windows, Classes ,WinSvc;

type
TServiceManager = class
private
{ Private declarations }
ServiceControlManager: SC_Handle;
ServiceHandle: SC_Handle;
protected
function DoStartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;
public
{ Public declarations }
function Connect(MachineName: PChar = nil; DatabaseName: PChar = nil;
Access: DWORD = SC_MANAGER_ALL_ACCESS): Boolean; // Access may be SC_MANAGER_ALL_ACCESS
function OpenServiceConnection(ServiceName: PChar): Boolean;
function StartService: Boolean; overload; // Simple start
function StartService(NumberOfArgument: DWORD; ServiceArgVectors: PChar): Boolean;overload; // More complex start
function StopService: Boolean;
procedure PauseService;
procedure ContinueService;
procedure ShutdownService;
function DisableService(ServiceName: PChar): Boolean;
function GetStatus: DWORD;
function ServiceRunning: Boolean;
function ServiceStopped: Boolean;
function InstallService(ServiceName, DisplayName: PChar; Filename: string): Boolean;
function UnInstallService(ServiceName: PChar): Boolean;
function EnumAllServicesName(strList: TStrings) : Boolean;
end;

implementation

{ TServiceManager }

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


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

procedure TServiceManager.PauseService;
var
ServiceStatus: TServiceStatus;
begin
{ Pause the service: attention not supported by all services }
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;

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

procedure TServiceManager.ShutdownService;
var
ServiceStatus: TServiceStatus;
begin
{ Shut service down: attention not supported by all services }
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 }
Result := 0;
QueryServiceStatus(ServiceHandle, ServiceStatus);
Result := ServiceStatus.dwCurrentState;
end;


function TServiceManager.DisableService(ServiceName: PChar): Boolean;
begin
Result := false;
ServiceControlManager:= OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
ServiceHandle:= OpenService(ServiceControlManager, ServiceName, SERVICE_CHANGE_CONFIG);
try
if ChangeServiceConfig(ServiceHandle,
SERVICE_NO_CHANGE,SERVICE_DISABLED,SERVICE_NO_CHANGE,
nil,nil,nil,nil,nil,nil,nil) then
Result := true;
finally
CloseServiceHandle(ServiceHandle);
CloseServiceHandle(ServiceControlManager);
end;
end;

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

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

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

function TServiceManager.InstallService(ServiceName, DisplayName: PChar; Filename: string): Boolean;
begin
Result := False;
ServiceControlManager := OpenSCManager(nil, nil, SC_MANAGER_CREATE_SERVICE);
if ServiceControlManager = 0 then
Exit;
try
ServiceHandle := CreateService(ServiceControlManager, ServiceName, DisplayName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL, PChar(Filename), nil, nil, nil, nil, nil);
if ServiceHandle<>0 then
Result:=true;
finally
CloseServiceHandle(ServiceHandle);
CloseServiceHandle(ServiceControlManager);
end;
end;

function TServiceManager.UnInstallService(ServiceName: PChar): Boolean;
begin
Result := False;
ServiceControlManager:=OpenSCManager(nil,nil,GENERIC_WRITE);
if ServiceControlManager = 0 then
Exit;
try
ServiceHandle:=OpenService(ServiceControlManager,ServiceName,_DELETE);
if DeleteService(ServiceHandle) then
Result:=true;
finally
CloseServiceHandle(ServiceHandle);
CloseServiceHandle(ServiceControlManager);
end;
end;

function TServiceManager.EnumAllServicesName(strList: TStrings) : Boolean;
type
pEnumServiceStatus = ^TEnumServiceStatus;
var
pEnumStatus: ^TEnumServiceStatus;
dwByteNeeded: DWORD;
dwNumOfService: DWORD;
dwResumeHandle: DWORD;
nI: integer;
begin
pEnumStatus := nil;
dwByteNeeded := 0;
dwResumeHandle := 0;
try
ServiceControlManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if not EnumServicesStatus(ServiceControlManager,
SERVICE_WIN32, //服務程式類型依需要修改(SERVICE_WIN32 or SERVICE_DRIVER)
SERVICE_ACTIVE or SERVICE_INACTIVE,
pEnumStatus^,
0,
dwByteNeeded,
dwNumOfService,
dwResumeHandle) then begin
if GetLastError = ERROR_MORE_DATA then begin
GetMem(pEnumStatus, dwByteNeeded);
if not EnumServicesStatus(ServiceControlManager,
SERVICE_WIN32, //服務程式類型依需要修改(SERVICE_WIN32 or SERVICE_DRIVER)
SERVICE_ACTIVE or SERVICE_INACTIVE,
pEnumStatus^,
dwByteNeeded,
dwByteNeeded,
dwNumOfService,
dwResumeHandle) then begin
result := false;
Exit;
end;
end
else begin
result := false;
exit;
end;
end;
strList.Clear;
for nI := 0 to dwNumOfService-1 do begin
strList.Add(TEnumServiceStatus(pEnumServiceStatus(pChar(pEnumStatus) + ni*SizeOf(TEnumServiceStatus))^).lpServiceName); //服務程式名稱
//TEnumServiceStatus(pEnumServiceStatus(pChar(pEnumStatus) + ni*SizeOf(TEnumServiceStatus))^).lpDisplayName //服務描述名稱
end;
CloseServiceHandle(ServiceControlManager);
Result := true;
finally
if Assigned(pEnumStatus) then FreeMem(pEnumStatus);
end;
end;

end.

相关信息:


欢迎光临本社区,您还没有登录,不能发贴子。请在 这里登录