You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C语言获取Windows系统服务的可执行文件路径?

使用C语言获取Windows服务的可执行文件路径

你提到的GetService、GetServiceDisplayName这类函数确实只能获取服务的名称、显示名这类基础信息,没法直接拿到可执行文件的系统路径。要解决这个问题,我们需要用到Windows API中的QueryServiceConfig函数——它专门用于查询服务的详细配置信息,其中就包含了服务可执行文件的路径。

核心思路

获取服务可执行路径的完整流程如下:

  1. 打开服务控制管理器(SCM):通过OpenSCManager函数获取SCM的句柄,这是操作服务的入口。
  2. 打开目标服务:用OpenService函数传入SCM句柄和目标服务的内部名称,得到对应服务的句柄。
  3. 查询服务配置:先调用一次QueryServiceConfig传入空缓冲区,获取所需的内存大小;再分配足够内存后第二次调用,拿到包含可执行路径的完整配置信息。
  4. 清理资源:及时关闭打开的句柄,释放分配的内存,避免资源泄漏。

完整示例代码

下面是一个可直接运行的示例,以查询Windows更新服务(内部服务名wuauserv)为例:

#include <windows.h>
#include <stdio.h>
#include <malloc.h>

int main() {
    SC_HANDLE hSCM = NULL;
    SC_HANDLE hService = NULL;
    LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
    DWORD dwBytesNeeded = 0;

    // 1. 打开服务控制管理器
    hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    if (hSCM == NULL) {
        printf("OpenSCManager failed! Error: %d\n", GetLastError());
        goto Cleanup;
    }

    // 2. 打开目标服务(替换成你需要查询的服务内部名称)
    hService = OpenService(hSCM, "wuauserv", SERVICE_QUERY_CONFIG);
    if (hService == NULL) {
        printf("OpenService failed! Error: %d\n", GetLastError());
        goto Cleanup;
    }

    // 3. 第一次调用QueryServiceConfig,获取所需缓冲区大小
    if (!QueryServiceConfig(hService, NULL, 0, &dwBytesNeeded)) {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("QueryServiceConfig (first call) failed! Error: %d\n", GetLastError());
            goto Cleanup;
        }
    }

    // 分配内存存储配置信息
    pServiceConfig = (LPQUERY_SERVICE_CONFIG)malloc(dwBytesNeeded);
    if (pServiceConfig == NULL) {
        printf("Memory allocation failed!\n");
        goto Cleanup;
    }

    // 第二次调用QueryServiceConfig,获取实际配置数据
    if (!QueryServiceConfig(hService, pServiceConfig, dwBytesNeeded, &dwBytesNeeded)) {
        printf("QueryServiceConfig (second call) failed! Error: %d\n", GetLastError());
        goto Cleanup;
    }

    // 输出服务可执行文件路径
    printf("Service Executable Path: %s\n", pServiceConfig->lpBinaryPathName);

Cleanup:
    // 清理所有资源
    if (pServiceConfig != NULL) {
        free(pServiceConfig);
    }
    if (hService != NULL) {
        CloseServiceHandle(hService);
    }
    if (hSCM != NULL) {
        CloseServiceHandle(hSCM);
    }

    return 0;
}

注意事项

  • 权限要求:查询部分系统服务需要管理员权限,否则会出现OpenService失败(错误码5,拒绝访问)的情况,记得以管理员身份运行程序。
  • 路径含参数处理:lpBinaryPathName返回的内容可能包含命令行参数,比如"C:\Windows\system32\svchost.exe" -k netsvcs。如果只需要纯路径,可以自行解析字符串,提取引号包裹的部分。
  • 服务名正确性:传入OpenService的必须是服务的内部名称(不是显示名),比如Windows更新服务的内部名是wuauserv,显示名是"Windows Update"。你可以通过services.msc查看服务的内部名称。

内容的提问来源于stack exchange,提问作者Poseidon Security

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:14:20