我有一个基于 DirectX 和 Windows 窗体的图形密集型应用程序。它有一个自动化和重放框架,围绕该框架构建了一个自动化测试系统。不幸的是,当在夜间构建期间无人看管地运行测试时,显示器处于非活动状态或与屏幕保护程序绑定,并且我们的 IT 安全策略不允许我们禁用它。
所以我的问题是:有没有办法对没有显示运行的应用程序进行“屏幕”捕获?我想确保显卡已启用,以便我的渲染管道相同,但测试框架不需要关心显示的状态。
任何帮助都非常感谢!
由于您提到了渲染管道,所以我假设您使用的是 Direct3d,如果是这样,您可以保存帧的后缓冲区。我还在使用 VB.Net + MDX 时这样做了
Dim tempSurface As Direct3D.Surface
tempSurface = device.GetBackBuffer(0, 0, Direct3D.BackBufferType.Mono)
Direct3D.SurfaceLoader.Save(tempFilename, Direct3D.ImageFileFormat.Png, tempSurface)
您可以轻松地转换为您选择的任何编程语言,它基本上是调用 Direct3d 的 API。不过,您需要将 backbuffer 和 Present 参数配置为
' Need to use flip to enable screen capture
presentParams.SwapEffect = Direct3D.SwapEffect.Flip
presentParams.PresentationInterval = Direct3D.PresentInterval.One
安装 VM 并在其中运行应用程序。如果您正在运行屏幕保护程序,我怀疑您的视频卡甚至会为应用程序生成 GUI。
如果我理解正确,您想要的只是截取特定应用程序的屏幕,而不是让结果受到可能正在运行的屏幕保护程序的影响?据我所知,只需GetDIBits
在正确窗口的 HDC 上进行操作就可以解决问题,而不必关心屏幕保护程序。
您可能会发现此代码非常慢,但是您可以通过设置PresentParams.PresentFlag = PresentFlag.LockableBackBuffer
此外,您不需要设置PresentInterval.One
or SwapEffect.Flip
,它们可以分别保留在 .Default 和 .Discard 。
(请注意,如果您使用多重采样,则此加速不起作用,请确保PresentParams.Multisample = Multisample.None
。如果您有 Nvidia 卡,您仍然可以通过在 Nvidia 控制面板中设置选项来将应用程序设置覆盖为您想要的设置来获得抗锯齿!)