You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Instsrv+Srvany配置自启动服务时DXGI捕获登录屏异常问题

问题根源与解决方案

这个问题的核心其实是Windows的会话隔离机制在搞鬼,咱们一步步拆解清楚:

为什么用Srvany注册成服务会失败?

从Windows Vista开始,微软引入了Session 0隔离机制:系统服务默认会在Session 0(非交互式的后台会话)运行,而登录屏幕、用户桌面这类交互式界面,都在Session 1及以后的独立会话里。

你用Instsrv+Srvany把dxgiSample.exe包装成服务后,它会默认在Session 0执行:

  • DXGI的EnumOutputs返回DXGI_ERROR_NOT_CURRENTLY_AVAILABLE(0x887A0022),是因为Session 0根本没有绑定任何物理显示输出,自然枚举不到可用的显示设备;
  • OpenInputDesktop返回错误1(ERROR_INVALID_FUNCTION),也是因为Session 0不存在可供交互的桌面环境,调用这个API自然无效。

为什么PsExec64能正常运行?

你用的参数PsExec64.exe -s -d -i dxgiSample.exe里,有两个关键作用:

  • -s让程序以系统权限运行,满足捕获登录屏幕所需的高权限要求;
  • -i是核心原因:这个参数指定程序在当前的交互式会话(也就是登录屏幕所在的Session)启动,这样程序就能访问到该会话绑定的显示输出和桌面对象,DXGI枚举、桌面操作自然都能正常工作。

解决办法:用任务计划替代Srvany实现自动启动

Srvany本质是把程序塞进Session 0的服务容器,没法直接让它跑到登录屏幕所在的交互式会话里,最可靠的替代方案是用任务计划程序,步骤如下:

  1. 打开「任务计划程序」,点击「创建任务」:
    • 「常规」选项卡:勾选「使用最高权限运行」,选择「不管用户是否登录都要运行」(确保登录屏幕阶段也能触发);
    • 「触发器」选项卡:添加触发器,选择「在工作站解锁时」(对应登录屏幕解锁场景)或者「在用户登录时」(根据你的捕获需求选择);
    • 「操作」选项卡:添加操作,选择「启动程序」,指定dxgiSample.exe的完整路径;
    • 「设置」选项卡:可选勾选「如果任务失败,每隔X分钟重试」,取消勾选「如果任务运行时间超过X小时就停止」。
  2. 保存任务后,重启系统测试,登录屏幕阶段程序应该能正常捕获,不会再出现之前的DXGI和桌面操作错误。

如果非要坚持用服务方式,也可以通过修改注册表或组策略让服务在交互式会话运行,但Windows 7及以后对这种方式做了严格限制,兼容性很差,不推荐。

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

火山引擎 最新活动