📄 userviceclass.pas
字号:
unit UServiceClass;
interface
uses
Windows, winsvc, classes;
type
TWin32Service = class;
TWin32SCManager = class;
TOnSCManagerChanged = procedure(AManager: TWin32SCManager) of object;
TOnServiceChanged = procedure(AService: TWin32Service) of object;
TWin32SCManager = class(TObject)
private
FHandle: SC_HANDLE;
FOnSCManagerChanged: TOnSCManagerChanged;
FOnServiceChanged: TOnServiceChanged;
FServiceList: TList;
function GetItems(index: Integer): TWin32Service;
function GetCount: Integer;
procedure Remove(AService: TWin32Service); //由TWin32Service调用
procedure Add(AService: TWin32Service); //由TWin32Service调用
procedure DoChanged;
procedure DoItemChanged(AItem: TWin32Service);
public
property Handle: SC_HANDLE read FHandle;
property OnSCManagerChanged: TOnSCManagerChanged read
FOnSCManagerChanged write FOnSCManagerChanged;
property OnServiceChanged: TOnServiceChanged read FOnServiceChanged
write FOnServiceChanged;
property Items[index: Integer]: TWin32Service read GetItems; default;
property Count: Integer read GetCount;
function Open(): boolean;
procedure Close();
procedure Sort(ACompare: TListSortCompare);
function Refresh(): boolean;
constructor Create; virtual;
destructor Destroy; override;
end;
TWin32Service = class(TObject)
private
FManager: TWin32SCManager;
FHandle: SC_HANDLE;
FName: string;
FDisplayName: string;
FServiceStatus: TServiceStatus;
public
property Name: string read FName;
property DisplayName: string read FDisplayName;
property ServiceStatus: TServiceStatus read FServiceStatus;
constructor Create(AManager: TWin32SCManager); virtual;
destructor Destroy; override;
procedure AssignFrom(AServiceStatus: PEnumServiceStatus);
procedure Stop;
procedure Uninstall;
procedure Start;
procedure QueryStatus;
end;
implementation
{ TWin32Service }
procedure TWin32Service.AssignFrom(AServiceStatus: PEnumServiceStatus);
begin
if Assigned(AServiceStatus) then
begin
FName := AServiceStatus^.lpServiceName;
FDisplayName := AServiceStatus^.lpDisplayName;
FServiceStatus := AServiceStatus^.ServiceStatus;
end;
end;
constructor TWin32Service.Create(AManager: TWin32SCManager);
begin
FManager := AManager;
if Assigned(FManager) then
begin
FManager.Add(Self);
end;
end;
destructor TWin32Service.Destroy;
begin
if Assigned(FManager) then
begin
if FHandle > 0 then
CloseServiceHandle(FHandle);
FHandle := 0;
FManager.Remove(Self);
end;
inherited;
end;
procedure TWin32Service.QueryStatus;
begin
if (FManager.Handle > 0) then
begin
FHandle := OpenService(FManager.Handle, PChar(FName), SERVICE_ALL_ACCESS);
if FHandle > 0 then
begin
if QueryServiceStatus(FHandle, FServiceStatus) then
FManager.DoItemChanged(Self);
CloseServiceHandle(FHandle);
FHandle := 0;
end;
end;
end;
procedure TWin32Service.Start;
var
tmp: PChar;
begin
if (FManager.Handle > 0) then
begin
tmp := nil;
FHandle := OpenService(FManager.Handle, PChar(FName), SERVICE_ALL_ACCESS);
if FHandle > 0 then
begin
StartService(FHandle, 0, tmp);
if QueryServiceStatus(FHandle, FServiceStatus) then
FManager.DoItemChanged(Self);
CloseServiceHandle(FHandle);
FHandle := 0;
end;
end;
end;
procedure TWin32Service.Stop;
begin
if (FManager.Handle > 0) then
begin
FHandle := OpenService(FManager.Handle, PChar(FName), SERVICE_ALL_ACCESS);
if FHandle > 0 then
begin
if ControlService(FHandle, SERVICE_CONTROL_STOP, FServiceStatus) then
begin
CloseServiceHandle(FHandle);
FManager.DoItemChanged(Self);
end;
FHandle := 0;
end;
end;
end;
procedure TWin32Service.Uninstall;
begin
if (FManager.Handle > 0) then
begin
FHandle := OpenService(FManager.Handle, PChar(FName), SERVICE_ALL_ACCESS);
if FHandle > 0 then
begin
DeleteService(FHandle);
if QueryServiceStatus(FHandle, FServiceStatus) then
FManager.DoItemChanged(Self);
CloseServiceHandle(FHandle);
FHandle := 0;
end;
end;
end;
{ TWin32SCManager }
constructor TWin32SCManager.Create;
begin
FHandle := 0;
FServiceList := TList.Create;
end;
destructor TWin32SCManager.Destroy;
begin
Close();
FServiceList.Free;
inherited;
end;
function TWin32SCManager.GetCount: Integer;
begin
Result := FServiceList.Count;
end;
function TWin32SCManager.GetItems(index: Integer): TWin32Service;
begin
if (index < FServiceList.Count) and (index >= 0) then
Result := TWin32Service(FServiceList[index])
else
Result := nil;
end;
function TWin32SCManager.Open: boolean;
var
item: TWin32Service;
bufferSize, srvCount, needBytes, resumeValue: Cardinal;
ppServiceStatus, pServiceStatus: PEnumServiceStatus;
i: Word;
begin
srvCount := 0;
resumeValue := 0;
pServiceStatus := nil;
ppServiceStatus := nil;
if (FHandle = 0) then begin
FHandle := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if (FHandle > 0) then begin
EnumServicesStatus(FHandle, SERVICE_WIN32, SERVICE_STATE_ALL,
ppServiceStatus^, 0, needBytes, srvCount, resumeValue);
if (needBytes > 0) then begin
bufferSize := needBytes;
GetMem(ppServiceStatus, bufferSize);
if Assigned(ppServiceStatus) then begin
if EnumServicesStatus(FHandle, SERVICE_WIN32, SERVICE_STATE_ALL,
ppServiceStatus^, bufferSize, needBytes, srvCount,
resumeValue) then begin
for i := 0 to srvCount -1 do
begin
pServiceStatus := PEnumServiceStatus(Cardinal(ppServiceStatus)
+ i * sizeof(TEnumServiceStatus));
item := TWin32Service.Create(Self);
item.AssignFrom(pServiceStatus);
end;
DoChanged;
end;
end;
end;
end;
end;
Result := FHandle > 0;
end;
function TWin32SCManager.Refresh: boolean;
begin
Close();
Result := Open();
end;
procedure TWin32SCManager.Close;
var
item: TWin32Service;
begin
if FHandle > 0 then
begin
while (FServiceList.Count > 0) do
begin
item := TWin32Service(FServiceList[0]);
item.Free;
end;
CloseServiceHandle(FHandle);
FHandle := 0;
end;
end;
procedure TWin32SCManager.Remove(AService: TWin32Service);
begin
FServiceList.Remove(AService);
end;
procedure TWin32SCManager.Add(AService: TWin32Service);
begin
FServiceList.Add(AService);
end;
procedure TWin32SCManager.DoChanged;
begin
if Assigned(FOnSCManagerChanged) then
FOnSCManagerChanged(Self);
end;
procedure TWin32SCManager.Sort(ACompare: TListSortCompare);
begin
FServiceList.Sort(ACompare);
DoChanged;
end;
procedure TWin32SCManager.DoItemChanged(AItem: TWin32Service);
begin
if Assigned(FOnServiceChanged) then
FOnServiceChanged(AItem);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -