已知Windows服务名称,
如何用delphi实现服务的开始与停止?
实现的函数是阻塞型的还是非阻塞型的?
如果是非阻塞型的,如何在开始或停止过程中监控服务当前的状态?好像是ReportStatus希望有完整的示例代码,谢谢!
如何用delphi实现服务的开始与停止?
实现的函数是阻塞型的还是非阻塞型的?
如果是非阻塞型的,如何在开始或停止过程中监控服务当前的状态?好像是ReportStatus希望有完整的示例代码,谢谢!
解决方案 »
- 怎么把文件打包进exe呢?
- 菜鸟求助(如何把sql server数据库中的内容刻入光盘里呢??急!!)
- 基于delphi-Midas三层结构程序的部署??
- dll调试问题 up也给分
- !!登陆!!
- procedure TList.Delete(Index: Integer);//Index成了一个变量但同时可以说Index是Integer这个类的实例吗
- 设置工具栏上按纽的状态
- 怎么得出系统默认打印机的纸张规格。也就是说怎么知道系统打印机可打哪些规格的纸张。
- 谁能让这个程序可以传参数??急急!!(源码见内)
- activex dll和ISAPI 有什么区别么???
- 想调用一个外部DLL的函数,但是这个函数没有返回值
- 一个排错问题,请各位帮帮忙!在此感谢
OpenService
QueryServiceStatus
OpenSCManager
StartService
ControlService
unit ServiceControl;
interface
uses
Windows, SysUtils, WinSvc, SvcMgr;
type
TServiceControl = class(TObject)
private
FMachine, FService: string;
function GetNTStatus: DWord;
function GetStatus: TCurrentStatus;
protected
public
function Start: Boolean;
function Stop: Boolean;
function Pause: Boolean;
function Continue: Boolean;
constructor Create(Service: string; Machine: string = '');
property NTStatus: DWord read GetNTStatus;
property Status: TCurrentStatus read GetStatus;
property Service: string read FService write FService;
property Machine: string read FMachine write FMachine;
published
end; { TServiceControl }
function StatusToNT(Status: TCurrentStatus): DWord;
function StatusFromNt(Status: DWord): TCurrentStatus;
implementation
function StatusToNT(Status: TCurrentStatus): DWord;
const
NTServiceStatus: array[TCurrentStatus] of DWord = (SERVICE_STOPPED,
SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING,
SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED);
begin
Result := NTServiceStatus[Status];
end;
function StatusFromNt(Status: DWord): TCurrentStatus;
const
CurrentStatus: array[1..7] of TCurrentStatus = (csStopped, csStartPending,
csStopPending, csRunning, csContinuePending, csPausePending, csPaused);
begin
Result := CurrentStatus[Status];
end;
{ TServiceControl }
constructor TServiceControl.Create(Service: string; Machine: string = '');
begin
FService := Service;
FMachine := Machine;
end;
function TServiceControl.GetStatus: TCurrentStatus;
begin
Result := StatusFromNT(GetNTStatus);
end;
function TServiceControl.GetNTStatus: DWord;
var
SvcMgr, Svc: SC_HANDLE;
SvcStatus: TServiceStatus;
begin
Result := 0;
SvcMgr := OpenSCManager(PChar(FMachine), nil, SC_MANAGER_CONNECT);
if SvcMgr = 0 then RaiseLastWin32Error;
try
Svc := OpenService(SvcMgr, PChar(FService), SERVICE_QUERY_STATUS);
if Svc = 0 then RaiseLastWin32Error;
try
if QueryServiceStatus(Svc, SvcStatus) then
Result := SvcStatus.dwCurrentState
else
RaiseLastWin32Error;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
end;
function TServiceControl.Start: Boolean;
var
psTemp: PChar;
CheckPoint: DWord;
SvcMgr, Svc: SC_HANDLE;
SvcStatus: TServiceStatus;
begin
SvcMgr := OpenSCManager(PChar(FMachine), nil, SC_MANAGER_CONNECT);
if SvcMgr = 0 then RaiseLastWin32Error;
try
Svc := OpenService(SvcMgr, PChar(FService), SERVICE_START or SERVICE_QUE
RY_STATUS);
if Svc = 0 then RaiseLastWin32Error;
try
psTemp := nil;
if StartService(Svc, 0, psTemp) then
begin
if not QueryServiceStatus(Svc, SvcStatus) then
RaiseLastWin32Error
else
with SvcStatus do
begin
while (SERVICE_RUNNING <> dwCurrentState) do
begin
CheckPoint := dwCheckPoint;
Sleep(dwWaitHint);
if not QueryServiceStatus(Svc, SvcStatus) then
Break;
if dwCheckPoint < CheckPoint then
Break;
end;
end;
end;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
Result := SERVICE_RUNNING = SvcStatus.dwCurrentState;
end;
function TServiceControl.Stop: Boolean;
var
CheckPoint: DWord;
SvcMgr, Svc: SC_HANDLE;
SvcStatus: TServiceStatus;
begin
SvcMgr := OpenSCManager(PChar(FMachine), nil, SC_MANAGER_CONNECT);
if SvcMgr = 0 then RaiseLastWin32Error;
try
Svc := OpenService(SvcMgr, PChar(FService), SERVICE_STOP or SERVICE_QUER
Y_STATUS);
if Svc = 0 then RaiseLastWin32Error;
try
if ControlService(Svc, SERVICE_CONTROL_STOP, SvcStatus) then
begin
if not QueryServiceStatus(Svc, SvcStatus) then
RaiseLastWin32Error
else
with SvcStatus do
begin
while (SERVICE_STOPPED <> dwCurrentState) do
begin
CheckPoint := dwCheckPoint;
Sleep(dwWaitHint);
if not QueryServiceStatus(Svc, SvcStatus) then
Break;
if dwCheckPoint < CheckPoint then
Break;
end;
end;
end;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
Result := SERVICE_STOPPED = SvcStatus.dwCurrentState;
end;
var
CheckPoint: DWord;
SvcMgr, Svc: SC_HANDLE;
SvcStatus: TServiceStatus;
begin
SvcMgr := OpenSCManager(PChar(FMachine), nil, SC_MANAGER_CONNECT);
if SvcMgr = 0 then RaiseLastWin32Error;
try
Svc := OpenService(SvcMgr, PChar(FService), SERVICE_PAUSE_CONTINUE or SE
RVICE_QUERY_STATUS);
if Svc = 0 then RaiseLastWin32Error;
try
if ControlService(Svc, SERVICE_CONTROL_CONTINUE, SvcStatus) then
begin
if not QueryServiceStatus(Svc, SvcStatus) then
RaiseLastWin32Error
else
with SvcStatus do
begin
while (SERVICE_RUNNING <> dwCurrentState) do
begin
CheckPoint := dwCheckPoint;
Sleep(dwWaitHint);
if not QueryServiceStatus(Svc, SvcStatus) then
Break;
if dwCheckPoint < CheckPoint then
Break;
end;
end;
end;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
Result := SERVICE_RUNNING = SvcStatus.dwCurrentState;
end;
function TServiceControl.Pause: Boolean;
var
CheckPoint: DWord;
SvcMgr, Svc: SC_HANDLE;
SvcStatus: TServiceStatus;
begin
SvcMgr := OpenSCManager(PChar(FMachine), nil, SC_MANAGER_CONNECT);
if SvcMgr = 0 then RaiseLastWin32Error;
try
Svc := OpenService(SvcMgr, PChar(FService), SERVICE_PAUSE_CONTINUE or SE
RVICE_QUERY_STATUS);
if Svc = 0 then RaiseLastWin32Error;
try
if ControlService(Svc, SERVICE_CONTROL_PAUSE, SvcStatus) then
begin
if not QueryServiceStatus(Svc, SvcStatus) then
RaiseLastWin32Error
else
with SvcStatus do
begin
while (SERVICE_PAUSED <> dwCurrentState) do
begin
CheckPoint := dwCheckPoint;
Sleep(dwWaitHint);
if not QueryServiceStatus(Svc, SvcStatus) then
Break;
if dwCheckPoint < CheckPoint then
Break;
end;
end;
end;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
Result := SERVICE_PAUSED = SvcStatus.dwCurrentState;
end;
end.
以前按着MSDN上的代码转换过来,是阻塞型的,如想非阻塞型,
可考虑将代码放在线程中执行.unit OperateService;
{
purpose: 操作Windows服务
}interfaceuses Windows, WinSvc;//启动服务
function StartSampleService(const ServiceName: PAnsiChar): LongBool;//停止服务
function StopSampleService(const ServiceName: PAnsiChar;
const fStopDependencies: LongBool; const dwTimeout: DWORD): LongBool;
//ServiceName - 服务名.
//fStopDependencies - 有依赖服务时,是否要停止.
//dwTimeout - 最大等待时间(毫秒)//得到服务的状态
function GetSampleServiceStatus(const ServiceName: PAnsiChar; var
lpServiceStatus:
TServiceStatus): LongBool;implementationuses Variants;function StartSampleService(const ServiceName: PAnsiChar): LongBool;
var
schSCManager, schService: SC_HANDLE;
ssStatus: TServiceStatus;
dwOldCheckPoint, dwStartTickCount, dwWaitTime: DWORD; lpServiceArgVectors: Pchar;
begin
Result := False; schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if schSCManager = 0 then
Exit; schService := OpenService(schSCManager, ServiceName, SERVICE_ALL_ACCESS);
if schService = 0 then
Exit;
try
lpServiceArgVectors := nil;
if not StartService(schService, 0, lpServiceArgVectors) then
Exit; if not QueryServiceStatus(schService, ssStatus) then
Exit; dwStartTickCount := GetTickCount;
dwOldCheckPoint := ssStatus.dwCheckPoint; while ssStatus.dwCurrentState = SERVICE_START_PENDING do
begin
dwWaitTime := ssStatus.dwWaitHint div 10;
if dwWaitTime < 1000 then
dwWaitTime := 1000
else if dwWaitTime > 10000 then
dwWaitTime := 10000; Sleep(dwWaitTime); if not QueryServiceStatus(schService, ssStatus) then
Break; if ssStatus.dwCheckPoint > dwOldCheckPoint then
begin
dwStartTickCount := GetTickCount;
dwOldCheckPoint := ssStatus.dwCheckPoint;
end
else if GetTickCount - dwStartTickCount > ssStatus.dwWaitHint then
Break;
end; if ssStatus.dwCurrentState = SERVICE_RUNNING then
Result := True;
finally
CloseServiceHandle(schService);
end;
end;function StopSampleService(const ServiceName: PAnsiChar;
const fStopDependencies: LongBool; const dwTimeout: DWORD): LongBool;
var
schSCManager, schService, hDepService: SC_HANDLE;
ssStatus: TServiceStatus;
dwStartTime: DWORD;
I, dwBytesNeeded, dwCount: DWORD;
lpDependencies: PEnumServiceStatus;
ess: TEnumServiceStatus;
begin
Result := False;
dwStartTime := GetTickCount; schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ENUMERATE_SERVICE);
if schSCManager = 0 then
Exit; schService := OpenService(schSCManager, ServiceName, SERVICE_ALL_ACCESS);
if schService = 0 then
Exit; if not QueryServiceStatus(schService, ssStatus) then
Exit; if ssStatus.dwCurrentState = SERVICE_STOPPED then
begin
Result := True;
Exit;
end; while ssStatus.dwCurrentState = SERVICE_STOP_PENDING do
begin
Sleep(ssStatus.dwWaitHint); if not QueryServiceStatus(schService, ssStatus) then
Exit; if ssStatus.dwCurrentState = SERVICE_STOPPED then
begin
Result := True;
Exit;
end; if (GetTickCount - dwStartTime > dwTimeout) then
Exit;
end;
if fStopDependencies then
begin
lpDependencies := nil; if EnumDependentServices(schService, SERVICE_ACTIVE, lpDependencies^, 0,
dwBytesNeeded, dwCount) then
begin
end
else
begin
if GetLastError <> ERROR_MORE_DATA then
Exit; lpDependencies := PEnumServiceStatus(HeapAlloc(GetProcessHeap,
0, dwBytesNeeded)); if not Assigned(lpDependencies) then
Exit; try
if not EnumDependentServices(schService, SERVICE_ACTIVE,
lpDependencies^,
dwBytesNeeded, dwBytesNeeded, dwCount) then
Exit; for I := 0 to dwCount - 1 do
begin
ess := lpDependencies^;
hDepService := OpenService(schSCManager, ess.lpServiceName,
SERVICE_STOP or
SERVICE_QUERY_STATUS);
if hDepService = 0 then
Exit;
try
if not ControlService(hDepService, SERVICE_CONTROL_STOP, ssStatus)
then
Exit; while ssStatus.dwCurrentState <> SERVICE_STOPPED do
begin
Sleep(ssStatus.dwWaitHint);
if not QueryServiceStatus(hDepService, ssStatus) then
Exit; if ssStatus.dwCurrentState = SERVICE_STOPPED then
begin
Inc(lpDependencies);
Break;
end; if GetTickCount - dwStartTime > dwTimeout then
Exit;
end;
finally
CloseServiceHandle(hDepService);
end;
Inc(lpDependencies);
end;
finally
HeapFree(GetProcessHeap, 0, lpDependencies);
end;
end;
end; if not ControlService(schService, SERVICE_CONTROL_STOP, ssStatus) then
Exit;
while ssStatus.dwCurrentState <> SERVICE_STOPPED do
begin
Sleep(ssStatus.dwWaitHint);
if not QueryServiceStatus(schService, ssStatus) then
Exit;
if ssStatus.dwCurrentState = SERVICE_STOPPED then
Break;
if GetTickCount - dwStartTime > dwTimeout then
Exit;
end;
Result := True;
end;function GetSampleServiceStatus(const ServiceName: PAnsiChar; var
lpServiceStatus:
TServiceStatus): LongBool;
var
schSCManager, schService: SC_HANDLE;
begin
Result := False; schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if schSCManager = 0 then
Exit; schService := OpenService(schSCManager, ServiceName, SERVICE_ALL_ACCESS);
if schService = 0 then
Exit;
try
if not QueryServiceStatus(schService, lpServiceStatus) then
Exit; Result := True;
finally
CloseServiceHandle(schService);
end;
end;end.