0

0

C++如何获取Windows系统服务列表_C++调用EnumServicesStatus方法【系统】

尼克

尼克

发布时间:2026-02-06 13:31:18

|

558人浏览过

|

来源于php中文网

原创

需以管理员权限调用OpenSCManager并指定SC_MANAGER_ENUMERATE_SERVICE权限,再调用EnumServicesStatus;若需完整服务信息应改用EnumServicesStatusEx并正确处理缓冲区重试与内存释放。

c++如何获取windows系统服务列表_c++调用enumservicesstatus方法【系统】

EnumServicesStatus 返回 ERROR_ACCESS_DENIED 怎么办

调用 EnumServicesStatus 失败并返回 ERROR_ACCESS_DENIED,不是代码写错了,而是权限不足。该函数需要打开服务控制管理器(SCM)的 SC_MANAGER_ENUMERATE_SERVICE 权限,而默认情况下普通用户进程只有 SC_MANAGER_CONNECT

解决办法是用更高权限打开 SCM:

  • 调用 OpenSCManager 时,把第二个参数(lpMachineName)设为 nullptr 或空字符串,第三个参数(dwDesiredAccess)必须显式指定为 SC_MANAGER_ENUMERATE_SERVICE(或至少包含它,比如 SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE
  • 确保你的程序以管理员身份运行——否则即使指定了正确权限,OpenSCManager 仍会失败并返回 NULL
  • 不要依赖 SC_MANAGER_ALL_ACCESS,它在非提升进程中必然失败;最小化权限原则下,只取 SC_MANAGER_ENUMERATE_SERVICE 就够了

EnumServicesStatusEx 和 EnumServicesStatus 选哪个

如果你只需要服务名、显示名、状态(运行/停止/暂停等),用 EnumServicesStatus 更轻量;但它的输出结构体 ENUM_SERVICE_STATUS 不包含启动类型(如自动、手动、禁用)、二进制路径、账户等关键信息。

要获取完整信息,必须用 EnumServicesStatusEx 并传入 SERVICE_WIN32 + SERVICE_ACTIVESERVICE_INACTIVE 过滤,同时指定 SC_ENUM_PROCESS_INFO 作为 dwInfoLevel。返回的是 ENUM_SERVICE_STATUS_PROCESS 结构体,其中 dwServiceTypedwStartTypedwErrorControllpBinaryPathName 等字段才真正有用。

立即学习C++免费学习笔记(深入)”;

注意:EnumServicesStatusEx 是 Windows XP SP1+ 才支持的 API,Win7 及以后系统没问题,但若需兼容老系统得降级处理。

缓冲区大小不够导致 ERROR_MORE_DATA 怎么安全重试

EnumServicesStatusEnumServicesStatusEx 都是典型的“先试探再分配”模式:第一次调用传入 0 缓冲区大小,API 通过 lpcbBytesNeeded 返回所需字节数;第二次才分配对应内存并重试。

Wand AI
Wand AI

一个无代码AI平台,帮助组织快速创建基于AI的业务解决方案

下载

常见错误是忽略 lpcbBytesNeeded 的更新,或者直接用固定大数组(比如 64KB)硬扛——这在服务很多时可能仍不够,且浪费内存。

安全做法是:

  • 首次调用前把 lpcbBytesNeeded 设为 0lpcServicesReturned 设为 0,缓冲区指针设为 nullptr
  • 检查返回值是否为 ERROR_MORE_DATA,是则按 *lpcbBytesNeeded 分配堆内存(别用数组)
  • 第二次调用后,务必检查返回值是否为 ERROR_SUCCESS,而不是只看指针是否非空
  • 记得用 LocalFree 释放 EnumServicesStatusEx 分配的内存(它内部用 LocalAlloc),别用 delete[]

遍历结果时 SERVICE_STATUS_PROCESS.dwCurrentState 值含义不明确

dwCurrentState 是一个整数,不是布尔值,常见值有:SERVICE_STOPPED(1)、SERVICE_START_PENDING(2)、SERVICE_STOP_PENDING(3)、SERVICE_RUNNING(4)、SERVICE_CONTINUE_PENDING(5)、SERVICE_PAUSE_PENDING(6)、SERVICE_PAUSED(7)。直接比较数字容易出错,应始终用宏定义。

特别注意:SERVICE_RUNNING 并不代表服务“健康”,只是状态机处于运行中;有些服务启动后立刻崩溃,状态仍可能是 RUNNING,需结合 dwWin32ExitCodedwServiceSpecificExitCode 判断实际运行情况。

另外,dwServiceType 字段常被误读:值为 SERVICE_WIN32_OWN_PROCESSSERVICE_WIN32_SHARE_PROCESS 才是传统 Win32 服务;SERVICE_KERNEL_DRIVERSERVICE_FILE_SYSTEM_DRIVER 属于内核驱动,普通应用通常不需要处理它们,过滤时可跳过。

服务列表本身没有排序保证,如果需要按名称或状态归类,得自己 std::sort 或用 std::map 组织。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

240

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

580

2024.03.01

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

397

2023.09.04

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

402

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

213

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1510

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

633

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

758

2024.03.22

1688阿里巴巴货源平台入口与批发采购指南
1688阿里巴巴货源平台入口与批发采购指南

本专题整理了1688阿里巴巴批发进货平台的最新入口地址与在线采购指南,帮助用户快速找到官方网站入口,了解如何进行批发采购、货源选择以及厂家直销等功能,提升采购效率与平台使用体验。

28

2026.02.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.6万人学习

Excel 教程
Excel 教程

共162课时 | 15.8万人学习

PHP基础入门课程
PHP基础入门课程

共33课时 | 2.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号