【问题标题】:Get the Description of a Service?获取服务描述?
【发布时间】:2012-02-03 23:30:03
【问题描述】:

我如何获得如下 Windows 服务的描述?

我尝试使用 Windows 注册表,但大多数服务似乎没有描述,或者描述值存储在 dll 中 - 所以这似乎是错误的方法。

例子:

Windows时间服务(W32Time),注册表中的描述显示为

@%SystemRoot%\system32\w32time.dll,-201

但在 Services.msc 中看到的实际描述是:

在所有客户端和服务器上保持日期和时间同步 网络。如果此服务停止,日期和时间同步 将不可用。如果此服务被禁用,任何服务 显式依赖它会启动失败。

-

我一直在 MSDN 网站上搜索,发现了这个:

SERVICE_DESCRIPTION structure

lpDescription

服务的描述。如果此成员为 NULL,则 描述保持不变。如果此值为空字符串 (""), 当前的描述被删除。

服务描述不得超过注册表值的大小 REG_SZ 类型。

此成员可以使用以下格式指定本地化字符串:

@[路径]dllname,-strID

标识符为strID的字符串是从dllname加载的;路径是 选修的。如需更多信息,请参阅RegLoadMUIString....

-

pszOutBuf [输出,可选]

指向接收字符串的缓冲区的指针。

以下形式的字符串接受特殊处理:

@[路径]\dllname,-strID

标识符为strID的字符串是从dllname加载的;路径是 选修的。如果 pszDirectory 参数不为 NULL,则目录为 附加到注册表数据中指定的路径。注意 dllname 可以包含要扩展的环境变量。

我认为这表明为什么查看注册表会显示 W32Time 描述为 @%SystemRoot%\system32\w32time.dll,-201

如果我理解正确,我需要读取内存中的 dll 名称并检索存储服务描述的 strID?

这一切都让我感到困惑,如果有人可以提供帮助,我将不胜感激。

我只需要获取一个服务的描述,它肯定不能这么复杂吗?

谢谢:)

【问题讨论】:

  • 谢谢你是什么意思,你是想讽刺还是什么?我问了一个我不确定的问题,我需要一些帮助和帮助。我在 MSDN 上阅读,但仍然不明白。如果我没有放下我研究的内容,很多人会认为我只是在寻找其他人来为我做这项工作。这不是我想要的,我只是想要一些关于如何做我认为这个网站的用途的建议。不过没必要讽刺。
  • 其实我不是[试图]讽刺。无论如何,您接受了 JEDI 贡献者为您工作的答案。这清楚地表明了。
  • Windows 能够使用资源来存储本地化数据(例如,事件日志消息使用相同的机制)。服务描述可以以同样的方式进行本地化,而且它变得更加重要,因为可以切换 Windows 语言,因此应用程序不能仅在设置时执行本地化任务。您需要使用您正在运行的系统的正确区域设置来读取 DLL 资源。但是,如果您使用 Service Manager API,Windows 会为您做这件事——这就是“发布”的方式。这些数据的内部存储可能会发生变化,API 更加稳定。
  • @user539484 不,它根本没有清楚地表明这一点。由于它似乎已经完成(即我不知道的绝地图书馆),我没有理由尝试重写它。如果有的话,我可以从 Jedi 库的单元中研究并查看代码是如何工作的。
  • @ldsandon 感谢您提供的信息。

标签: delphi delphi-xe


【解决方案1】:

在所有版本的 Delphi 中,JEDI JCL 包含获取服务的友好描述所需的所有内容,以及与服务控制 API 相关的所有内容。

JclSvcCtrl.pas 单元中的 TJclSCManager 类包含一个属性 Services,其中包括每个注册的服务的名称和描述,并且还允许您执行启动、停止、启用和禁用服务等操作。

更新:来自 ldsandon 的另一个答案指出,Delphi RTL 显然已经在 XE2 的 WinSvc 单元中包含了这个。请参阅下面有关 QueryServiceConfig2 的答案。感谢 ldsandon 指出这一事实。

【讨论】:

  • 如果不想依赖 Jedi,可以调用 win32 服务控制管理器 API。
  • 也可以从绝地中提取几个单元到一个文件夹中,避免重写 API 包装器。
  • 您实际上并不需要“重写 API 包装器”。 Delphi 可以直接调用 API,所有需要的类型和常量都已在 RTL AFAIK 中声明。如果需求足够简单,那只是 API 调用的问题。如果目标是编写服务管理应用程序,那就另当别论了。
  • 喂。没有人懂英语。直接调用 API 的代码不是零行代码,也不是一行代码。涉及到记录类型声明、常量等。所有这些东西都在 JEDI JCL 中,只需剪切和粘贴,而不是重新输入,这就是我要说的'
  • 减少单位是个好主意。我刚刚注意到有多少单位链接到其他单位,哪些单位链接到其他单位,哪些单位链接到其他单位等等。绝地图书馆中似乎使用了很多单位!
【解决方案2】:

致电QueryServiceConfig2(您还会在那里找到一个 C 示例)。

无论您需要对服务做什么,都应通过Service Manager API 完成。注册表数据应被视为操作系统的“私有”数据。

【讨论】:

    【解决方案3】:

    使用 WMI 是另一种直接使用 Windows API 的方法,例如借助(免费)API 代码生成器

    WMI Delphi Code Creator

    WMI Delphi Code Creator 工具允许您生成 Object Pascal 和 C++ 代码来访问 WMI(Windows 管理规范) 类、事件和方法。

    【讨论】:

    • 请注意 WMI 通过 COM,因为它被设计用于无法直接调用 Windows API 的工具(脚本语言等)。它可能更容易使用(虽然有点“重”),而 API 通常会在出现问题时提供更好的控制和更好的错误代码。
    • 很好的信息,感谢您的谨慎,我一直在您链接的维基百科网站上阅读有关 WMI 的信息,当然有很多信息需要消化!
    【解决方案4】:

    您使用的是 Unicode 吗? RegLoadMUIString function 的备注说只支持 Unicode 版本。

    RegLoadMUIString 函数仅支持 Unicode。虽然 声明了此函数的 Unicode (W) 和 ANSI (A) 版本, RegLoadMUIStringA 函数返回 ERROR_CALL_NOT_IMPLEMENTED。 应用程序应显式调用 RegLoadMUIStringW 或指定 Unicode 作为平台调用 (PInvoke) 调用中的字符集。

    你试过直接拨打RegLoadMUIStringW吗?

    【讨论】:

      【解决方案5】:

      您也可以查看the GLibWMI library。用于 WMI 的免费(包括源代码)库。包括一个名为 TServiceInfo 的组件。 还包括一个工作 wirh 服务的演示。

      使用此组件,您可以在 Win32_Service 类中访问;您可以查看the properties and structure here。

      问候

      【讨论】:

        猜你喜欢
        • 2020-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多