DELPHI写的服务程序在服务管理器中显示“描述”


本文整理自网络,侵删。

 
DELPHI写的服务程序,可以在XP系统的服务管理器中显示“名称”,但没有与“描述”相对应的发生,“描述”都是显示空白。


如何加入自己服务程序的“描述”内容呢?

目前基本有两种方法:
1、修改注册表,在
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet001\Services下找到自己的服务名称键值,然后加入一个名为Description的字符串字段,字段内容就是描述的内容。
这种方法通过实验是有效的,但因为不是通过API实现,而是直接写注册表,不太清楚适用性如何,不同的系统不知是否通用。

2、可通过ChangeServiceConfig2函数实现对服务的描述的修改。网上的ChangeServiceConfig2函数举例都根本无法成功运行,通过摸索改进,现提供ChangeServiceConfig2的正确用法如下,可成功有效地修改服务程序的描述。
程序代码

var
  sdBuf: SERVICE_DESCRIPTION;
  hSCManager, ServiceHandle: SC_Handle;
begin
  hSCManager := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_Access);
  if hSCManager<>0 then
  try
    ServiceHandle := OpenService(hSCManager, PChar(ShutDownMonService.Name), SERVICE_CHANGE_CONFIG);
    if ServiceHandle<>0 then
    try
      sdBuf.lpDescription := '我们的描述写在这里。';
      ChangeServiceConfig2(ServiceHandle, SERVICE_CONFIG_DESCRIPTION, @sdBuf);
    finally
      CloseServiceHandle(ServiceHandle);
    end;
  finally
    CloseServiceHandle(hSCManager);
  end;
end;

以上的代码建议加在Service的AfterInstall事件中,当服务安装成功后自动对描述进行修改。一次性即可。

注意需要引用WinSvc, WinSvcEx两个单元,其中WinSvcEx的内容如下
程序代码

unit WinSvcEx;

interface

uses Windows, WinSvc;

const 
// 
// Service config info levels 
// 
SERVICE_CONFIG_DESCRIPTION = 1; 
SERVICE_CONFIG_FAILURE_ACTIONS = 2;

// 
// DLL name of imported functions 
// 
AdvApiDLL = 'advapi32.dll'; 
type 
// 
// Service description string 
// 
PServiceDescriptionA = ^TServiceDescriptionA; 
PServiceDescriptionW = ^TServiceDescriptionW; 
PServiceDescription = PServiceDescriptionA; 
{$EXTERNALSYM _SERVICE_DESCRIPTIONA} 
_SERVICE_DESCRIPTIONA = record 
lpDescription : PAnsiChar; 
end; 
{$EXTERNALSYM _SERVICE_DESCRIPTIONW} 
_SERVICE_DESCRIPTIONW = record 
lpDescription : PWideChar; 
end; 
{$EXTERNALSYM _SERVICE_DESCRIPTION} 
_SERVICE_DESCRIPTION = _SERVICE_DESCRIPTIONA; 
{$EXTERNALSYM SERVICE_DESCRIPTIONA} 
SERVICE_DESCRIPTIONA = _SERVICE_DESCRIPTIONA; 
{$EXTERNALSYM SERVICE_DESCRIPTIONW} 
SERVICE_DESCRIPTIONW = _SERVICE_DESCRIPTIONW; 
{$EXTERNALSYM SERVICE_DESCRIPTION} 
SERVICE_DESCRIPTION = _SERVICE_DESCRIPTIONA; 
TServiceDescriptionA = _SERVICE_DESCRIPTIONA; 
TServiceDescriptionW = _SERVICE_DESCRIPTIONW; 
TServiceDescription = TServiceDescriptionA;

// 
// Actions to take on service failure 
// 
{$EXTERNALSYM _SC_ACTION_TYPE} 
_SC_ACTION_TYPE = (SC_ACTION_NONE, SC_ACTION_RESTART, SC_ACTION_REBOOT, SC_ACTION_RUN_COMMAND); 
{$EXTERNALSYM SC_ACTION_TYPE} 
SC_ACTION_TYPE = _SC_ACTION_TYPE;

PServiceAction = ^TServiceAction; 
{$EXTERNALSYM _SC_ACTION} 
_SC_ACTION = record 
aType : SC_ACTION_TYPE; 
Delay : DWORD; 
end; 
{$EXTERNALSYM SC_ACTION} 
SC_ACTION = _SC_ACTION; 
TServiceAction = _SC_ACTION;

PServiceFailureActionsA = ^TServiceFailureActionsA; 
PServiceFailureActionsW = ^TServiceFailureActionsW; 
PServiceFailureActions = PServiceFailureActionsA; 
{$EXTERNALSYM _SERVICE_FAILURE_ACTIONSA} 
_SERVICE_FAILURE_ACTIONSA = record 
dwResetPeriod : DWORD; 
lpRebootMsg : LPSTR; 
lpCommand : LPSTR; 
cActions : DWORD; 
lpsaActions : ^SC_ACTION; 
end; 
{$EXTERNALSYM _SERVICE_FAILURE_ACTIONSW} 
_SERVICE_FAILURE_ACTIONSW = record 
dwResetPeriod : DWORD; 
lpRebootMsg : LPWSTR; 
lpCommand : LPWSTR; 
cActions : DWORD; 
lpsaActions : ^SC_ACTION; 
end; 
{$EXTERNALSYM _SERVICE_FAILURE_ACTIONS} 
_SERVICE_FAILURE_ACTIONS = _SERVICE_FAILURE_ACTIONSA; 
{$EXTERNALSYM SERVICE_FAILURE_ACTIONSA} 
SERVICE_FAILURE_ACTIONSA = _SERVICE_FAILURE_ACTIONSA; 
{$EXTERNALSYM SERVICE_FAILURE_ACTIONSW} 
SERVICE_FAILURE_ACTIONSW = _SERVICE_FAILURE_ACTIONSW; 
{$EXTERNALSYM SERVICE_FAILURE_ACTIONS} 
SERVICE_FAILURE_ACTIONS = _SERVICE_FAILURE_ACTIONSA; 
TServiceFailureActionsA = _SERVICE_FAILURE_ACTIONSA; 
TServiceFailureActionsW = _SERVICE_FAILURE_ACTIONSW; 
TServiceFailureActions = TServiceFailureActionsA;

/////////////////////////////////////////////////////////////////////////// 
// API Function Prototypes 
/////////////////////////////////////////////////////////////////////////// 
TQueryServiceConfig2 = function (hService : SC_HANDLE; dwInfoLevel : DWORD; lpBuffer : pointer; 
cbBufSize : DWORD; var pcbBytesNeeded) : BOOL; stdcall; 
TChangeServiceConfig2 = function (hService : SC_HANDLE; dwInfoLevel : DWORD; lpInfo : pointer) : BOOL; stdcall;

var 
hDLL : THandle ; 
LibLoaded : boolean ;

var 
OSVersionInfo : TOSVersionInfo;

{$EXTERNALSYM QueryServiceConfig2A} 
QueryServiceConfig2A : TQueryServiceConfig2; 
{$EXTERNALSYM QueryServiceConfig2W} 
QueryServiceConfig2W : TQueryServiceConfig2; 
{$EXTERNALSYM QueryServiceConfig2} 
QueryServiceConfig2 : TQueryServiceConfig2;

{$EXTERNALSYM ChangeServiceConfig2A} 
ChangeServiceConfig2A : TChangeServiceConfig2; 
{$EXTERNALSYM ChangeServiceConfig2W} 
ChangeServiceConfig2W : TChangeServiceConfig2; 
{$EXTERNALSYM ChangeServiceConfig2} 
ChangeServiceConfig2 : TChangeServiceConfig2;

implementation

initialization 
OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo); 
GetVersionEx(OSVersionInfo); 
if (OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT) and (OSVersionInfo.dwMajorVersion >= 5) then 
begin 
if hDLL = 0 then 
begin 
hDLL:=GetModuleHandle(AdvApiDLL); 
LibLoaded := False; 
if hDLL = 0 then 
begin 
hDLL := LoadLibrary(AdvApiDLL); 
LibLoaded := True; 
end; 
end;

if hDLL <> 0 then 
begin 
@QueryServiceConfig2A := GetProcAddress(hDLL, 'QueryServiceConfig2A'); 
@QueryServiceConfig2W := GetProcAddress(hDLL, 'QueryServiceConfig2W'); 
@QueryServiceConfig2 := @QueryServiceConfig2A; 
@ChangeServiceConfig2A := GetProcAddress(hDLL, 'ChangeServiceConfig2A'); 
@ChangeServiceConfig2W := GetProcAddress(hDLL, 'ChangeServiceConfig2W'); 
@ChangeServiceConfig2 := @ChangeServiceConfig2A; 
end; 
end 
else 
begin 
@QueryServiceConfig2A := nil; 
@QueryServiceConfig2W := nil; 
@QueryServiceConfig2 := nil; 
@ChangeServiceConfig2A := nil; 
@ChangeServiceConfig2W := nil; 
@ChangeServiceConfig2 := nil; 
end;

finalization 
if (hDLL <> 0) and LibLoaded then 
FreeLibrary(hDLL);

end.

相关阅读 >>

Delphi 获取打印机纸型的例子

Delphi 校验文件大小

Delphi 取得ie下面输入框内容

Delphi实现百度地图经纬度与地址互转

Delphi listview用法

Delphi 二进制值转换十六进制 bintohex和hextobin

Delphi 通过 shgetspecialfolderlocation、shgetpathfromidlist 函数获取常用路径

Delphi 极速字符串替换函数

Delphi android调用授权管理打开通知监听服务

Delphi 万年历 程序源码下部分(包括:农历计算、24节气、星期计算、属相)

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...