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

Delphi 10.4/11调用EnumServicesStatus报类型不兼容及访问违例问题

问题根因

Delphi 10.4及后续版本调整了Winapi.WinSvc单元中EnumServicesStatus的函数声明:旧版本该API的缓冲区参数按值接收TEnumServiceStatus(即_ENUM_SERVICE_STATUSW)类型,传数组首元素即可正常调用;新版本将该参数明确为LPENUM_SERVICE_STATUSW(_ENUM_SERVICE_STATUSW的指针类型),原有代码传ssa^[0](结构体值类型)自然会报类型不匹配错误。

之前把数组元素改为LPENUM_SERVICE_STATUSW后触发访问违例,是因为LPENUM_SERVICE_STATUSW本身就是指针类型,此时定义的数组是4096个指针的集合,New(ssa)分配的内存空间远小于存储服务状态结构体所需的大小,API写入数据时直接越界,就会触发内存访问错误。

修复方案

不需要修改原有的数组类型定义,仅需调整EnumServicesStatus调用时的参数,传入数组首元素的地址即可匹配新版本的指针参数要求。核心修正代码如下:

// 保留原有类型定义,不要将数组元素改为LPENUM_SERVICE_STATUSW
type
  TSvcA = array[0..cnMaxServices] of TEnumServiceStatus;
  PSvcA = ^TSvcA;

// 其余变量定义、SC管理器连接逻辑保持不变

EnumServicesStatus(
  schm,
  dwServiceType,
  dwServiceState,
  @ssa^[0], // 新增@取地址符,传入缓冲区首指针
  SizeOf(ssa^),
  nBytesNeeded,
  nServices,
  nResumeHandle );

// 后续遍历列表、释放内存、关闭句柄的逻辑无需改动
补充说明

当前代码默认单次调用即可获取全量服务,若系统内服务总数超过定义的cnMaxServices = 4096阈值,需要循环调用EnumServicesStatus,直到nResumeHandle返回0才能拿全所有服务,否则会出现服务列表缺失的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:39:27