📄 uprocessservice.pas
字号:
//unit UProcessService: List Service and Operate Service;
unit UProcessService;
interface
uses WinSvc,Classes,Windows,Sysutils;
function ServiceGetList(
sMachine : string;
dwServiceType,
dwServiceState : Dword;
slServicesList : TStrings )
: boolean; //List service
function ServiceGetKeyName(
sMachine,
sServiceDispName : string ) : string; //convert displayname to keyname
function ServiceGetDisplayName(
sMachine,
sServiceKeyName : string ) : string; //conver keyname to displayname
function ServiceGetStatus(
sMachine,
sService : string ) : DWord; //Get service status
function ServiceRunning(
sMachine,
sService : string ) : boolean;
function ServiceStopped(
sMachine,
sService : string ) : boolean;
function ServiceStart(
sMachine,
sService : string ) : boolean;
function ServiceStop(
sMachine,
sService : string ) : boolean;
implementation
const
//
// Service Types
//
SERVICE_KERNEL_DRIVER = $00000001;
SERVICE_FILE_SYSTEM_DRIVER = $00000002;
SERVICE_ADAPTER = $00000004;
SERVICE_RECOGNIZER_DRIVER = $00000008;
SERVICE_DRIVER =
(SERVICE_KERNEL_DRIVER or
SERVICE_FILE_SYSTEM_DRIVER or
SERVICE_RECOGNIZER_DRIVER);
SERVICE_WIN32_OWN_PROCESS = $00000010;
SERVICE_WIN32_SHARE_PROCESS = $00000020;
SERVICE_WIN32 =
(SERVICE_WIN32_OWN_PROCESS or
SERVICE_WIN32_SHARE_PROCESS);
SERVICE_INTERACTIVE_PROCESS = $00000100;
SERVICE_TYPE_ALL =
(SERVICE_WIN32 or
SERVICE_ADAPTER or
SERVICE_DRIVER or
SERVICE_INTERACTIVE_PROCESS);
//-------------------------------------
// Get a list of services
//
// return TRUE if successful
//
// sMachine:
// machine name, ie: \\SERVER
// empty = local machine
//
// dwServiceType
// SERVICE_WIN32,
// SERVICE_DRIVER or
// SERVICE_TYPE_ALL
//
// dwServiceState
// SERVICE_ACTIVE,
// SERVICE_INACTIVE or
// SERVICE_STATE_ALL
//
// slServicesList
// TStrings variable to storage
//
{----在WindowsNT下,各种Service都存在service control manager database中,因此我们可以通过对service control manager database进行操作来实现对Service的编程。下面介绍常用的函数:
1:SC_HANDLE OpenSCManager(LPCTSTR lpszMachineName,
LPCTSTR lpszDatabaseName,
DWORD fdwDesiredAccess);
----Open SCManager 函数打开指定计算机上的service control manager database。其中参数lpszMachineName指定计算机名,若为空则指定为本机。参数lpszDatabaseName指定要打开的service control manager database,默认为空。
----参数fdwDesiredAccess指定操作的权限,可以为下面取值之一
SC_MANAGER_ALL_ACCESS //所有权限
SC_MANAGER_CONNECT //允许连接service control manager
SC_MANAGER_CREATE_SERVICE //允许创建服务对象并把它加入service control manager database
SC_MANAGER_ENUMERATE_SERVICE //允许枚举service control manager database中的服务SC_MANAGER_LOCK //允许锁住service control manager database
SC_MANAGER_QUERY_LOCK_STATUS //允许获取servicecontrolmanagerdatabase的封锁信息
----函数返回值:函数执行成功则返回一个指向service control manager database的句柄,失败则返回NULL。
2:SC_HANDLE OpenService(SC_HANDLE schSCManager,
LPCTSTR lpszServiceName,
DWORD fdwDesiredAccess);
----OpenService函数打开指定的Service。
----其中参数schSCManager是指向service control manager database的句柄,由OpenSCManager函数返回。
----参数lpszServiceName要打开的服务的名字,注意大小写。
----参数fdwDesiredAccess指定操作的权限,可以为下面取值之一
SERVICE_ALL_ACCESS //所有权限
SERVICE_CHANGE_CONFIG //允许更改服务的配置
SERVICE_ENUMERATE_DEPENDENTS //允许获取依赖于该服务的其他服务
SERVICE_INTERROGATE //允许立即获取服务状态
SERVICE_PAUSE_CONTINUE //允许暂停和唤醒服务
SERVICE_QUERY_CONFIG //允许获取服务配置
SERVICE_QUERY_STATU //允许通过访问service control manager获取服务状态
SERVICE_START //允许启动服务
SERVICE_STOP //允许停止服务
SERVICE_USER_DEFINE_CONTROL //允许用户指定特殊的服务控制码
----函数返回值:函数执行成功则返回指向某项服务的句柄,失败则返回NULL。
3:BOOL QueryServiceStatus(SC_HANDLE schService,LPSERVICE_STATUS lpssServiceStatus);
----QueryServiceStatus函数返回指定服务的当前状态。
----其中参数schService是指向某项服务的句柄,由OpenService函数返回,且必须SERVICE_QUERY_STATUS的权限。
----参数lpssServiceStatus中存放返回的服务状态信息,结构如下
typedefstruct_SERVICE_STATUS{
DWORD dwServiceType; //服务类型
DWORD dwCurrentState; //当前状态
DWORD dwControlsAccepted; //服务可接受的控制码
DWORD dwWin32ExitCode; //Win32出错代码
DWORD dwServiceSpecificExitCode;//服务出错代码
DWORD dwCheckPoint; //用于跟踪服务长时间操作
DWORD dwWaitHint; //服务某一操作的最大允许时间,以毫秒为单位
}//SERVICE_STATUS,*LPSERVICE_STATUS;
{----函数返回值:函数执行成功则返回True,失败则返回False。
4:BOOLStartService(SC_HANDLE schService,DWORD dwNumServiceArgs,LPCTSTR * lpszServiceArgs);
----StartService函数启动指定的服务。
----其中参数schService是指向某项服务的句柄,由OpenService函数返回,且必须有SERVICE_START的权限。
----dwNumServiceArgs为启动服务所需的参数的个数。
----lpszServiceArgs为启动服务所需的参数。函数返回值:函数执行成功则返回True,失败则返回False。
5:BOOL ControlService(SC_HANDLE hService,DWORD dwControl,LPSERVICE_STATUS lpServiceStatus);
----ControlService函数向Win32service发送控制码。
----其中参数hService是指向某项服务的句柄,由OpenService函数返回。
----参数dwControl为控制码,常用的有
SERVICE_CONTROL_STOP //停止服务
SERVICE_CONTROL_PAUSE //暂停服务
SERVICE_CONTROL_CONTINUE //唤醒暂停的服务
SERVICE_CONTROL_INTERROGATE//刷新某服务的状态
----参数lpServiceStatus指向SERVICE_STATUS结构,用于存放该服务最新的状态信息。
----函数返回值:函数执行成功则返回True,失败则返回False。
6:BOOL EnumServicesStatus(SC_HANDLE hSCManager,
DWORD dwServiceType,
DWORD dwServiceState,
LPENUM_SERVICE_STATUS lpServices,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded,
LPDWORD lpServicesReturned,
LPDWORD lpResumeHandle);
----EnumServicesStatus函数用于枚举NT下存在的Service。
----其中参数hSCManager是指向service control manager database的句柄,由OpenSCManager函数返回,且必须有SC_MANAGER_ENUMERATE_SERVICE的权限。
----参数dwServiceType指定按服务的类型枚举。
----参数dwServiceState指定按服务的状态枚举。
----参数lpServices指向ENUM_SERVICE_STATUS结构,用于存放返回的服务的名字和状态信息。
----参数cbBufSize返回参数lpServices的长度,以字节为单位。
----参数pcbBytesNeeded返回获取剩余的Service所需字节的个数。
----参数lpServicesReturned返回服务的个数。
----参数lpResumeHandle,当第一次调用时该参数为0,当该函数再次被调用以获取另外的信息时,该参数表示下一个被读的Service。
----函数返回值:函数执行成功则返回True,失败则返回False。
----值得注意的是通常情况下该函数返回的结果为FALSE,我们可以调用GetLastError()来获取进一步信息。因为一台机器上有多种服务存在,所以GetLastError()应为ERROR_MORE_DATA,此时应再次调用EnumServicesStatus函数以获取正确的Service列表。
}
function ServiceGetList(
sMachine : string;
dwServiceType,
dwServiceState : Dword;
slServicesList : TStrings )
: boolean;
const
//
// assume that the total number of
// services is less than 4096.
// increase if necessary
cnMaxServices = 4096;
type
TSvcA = array[0..cnMaxServices]
of TEnumServiceStatus;
PSvcA = ^TSvcA;
var
//
// temp. use
j : integer;
//
// service control
// manager handle
schm : SC_Handle;
//
// bytes needed for the
// next buffer, if any
nBytesNeeded,
//
// number of services
nServices,
//
// pointer to the
// next unread service entry
nResumeHandle : DWord;
//
// service status array
ssa : PSvcA;
begin
Result := false;
// connect to the service
// control manager
schm := OpenSCManager(
PChar(sMachine),
Nil,
SC_MANAGER_ALL_ACCESS);
// if successful...
if(schm > 0)then
begin
nResumeHandle := 0;
New(ssa);
EnumServicesStatus(
schm,
dwServiceType,
dwServiceState,
ssa^[0],
SizeOf(ssa^),
nBytesNeeded,
nServices,
nResumeHandle );
//
// assume that our initial array
// was large enough to hold all
// entries. add code to enumerate
// if necessary.
//
for j := 0 to nServices-1 do
begin
slServicesList.
Add( StrPas(
ssa^[j].lpDisplayName ) );
end;
Result := true;
Dispose(ssa);
// close service control
// manager handle
CloseServiceHandle(schm);
end;
end;
function ServiceGetKeyName(
sMachine,
sServiceDispName : string ) : string;
var
//
// service control
// manager handle
schm : SC_Handle;
//
// max key name len
nMaxNameLen : DWord;
//
// temp. string
psServiceName : PChar;
begin
Result := '';
// expect a service key
// name shorter than 255
// characters
nMaxNameLen := 255;
// connect to the service
// control manager
schm := OpenSCManager(
PChar(sMachine),
Nil,
SC_MANAGER_CONNECT);
// if successful...
if(schm > 0)then
begin
psServiceName :=
StrAlloc(nMaxNameLen+1);
if(nil <> psServiceName)then
begin
if( GetServiceKeyName(schm,PChar(sServiceDispName),
psServiceName, //返回值
nMaxNameLen ) )then
begin
psServiceName
[nMaxNameLen] := #0;
Result :=
StrPas( psServiceName );
end;
StrDispose(psServiceName);
end;
// close service control
// manager handle
CloseServiceHandle(schm);
end;
end;
function ServiceGetDisplayName(
sMachine,
sServiceKeyName : string ) : string;
var
//
// service control
// manager handle
schm : SC_Handle;
//
// max display name len
nMaxNameLen : DWord;
//
// temp. string
psServiceName : PChar;
begin
Result := '';
// expect a service display
// name shorter than 255
// characters
nMaxNameLen := 255;
// connect to the service
// control manager
schm := OpenSCManager(
PChar(sMachine),
Nil,
SC_MANAGER_CONNECT);
// if successful...
if(schm > 0)then
begin
psServiceName :=
StrAlloc(nMaxNameLen+1);
if(nil <> psServiceName)then
begin
if( GetServiceDisplayName(
schm,
PChar(sServiceKeyName),
psServiceName, //返回值
nMaxNameLen ) )then // 长度
begin
psServiceName
[nMaxNameLen] := #0;
Result :=
StrPas( psServiceName );
end;
StrDispose(psServiceName);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -