Windows窗体:非图形运行时的屏幕截图(即屏幕保护程序处于活动状态)
题
我有一个图形密集型的应用程序,它基于DirectX和Windows Forms构建。它有一个自动化和重放框架,围绕它构建了一个自动化测试系统。不幸的是,当测试在夜间构建期间无人值守时,显示器处于非活动状态或与屏幕保护程序绑定,我们的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。
如果我理解正确,你想要的只是抓住特定应用程序的屏幕抓取而不是让结果受到可能正在运行的屏幕保护程序的影响?据我所知,只需在正确的窗口的HDC上执行 GetDIBits
即可,而不关心屏幕保护程序。
您可能会发现此代码非常慢,但是您可以通过设置 PresentParams.PresentFlag = PresentFlag.LockableBackBuffer
此外,您不需要设置 PresentInterval.One
或 SwapEffect.Flip
,它们可以保留在.Default和.Discard中。
(请注意,如果您使用多重采样,此加速不起作用,请确保 PresentParams.Multisample = Multisample.None
。如果您有Nvidia卡,您仍然可以通过设置选项获得抗锯齿功能在Nvidia控制面板中将应用程序设置覆盖到您想要的位置!)