Windows Forms:非グラフィカルに実行するときのスクリーンキャプチャ(つまり、スクリーンセーバーがアクティブ)
質問
非常にグラフィックスを多用し、DirectXおよびWindows Forms上に構築されたアプリケーションがあります。自動化されたテストシステムを構築する自動化およびリプレイフレームワークがあります。残念ながら、ナイトリービルド中にテストが無人で実行されると、ディスプレイは非アクティブになるか、スクリーンセーバーに縛られ、ITセキュリティポリシーでは無効にできません。
だから私の質問:" screen"を行う方法はありますか?ディスプレイなしで実行されているアプリケーションのキャプチャ?レンダリングパイプラインが同じになるようにグラフィックカードが使用されるようにしますが、テストフレームワークはディスプレイの状態を気にする必要はありません。
大いに感謝します!
解決
レンダリングパイプラインについて説明したので、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を呼び出しているため、任意のプログラミング言語を使用して簡単に変換できます。ただし、バックバッファと現在のパラメータを次のように設定する必要があります
' 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コントロールパネルで、アプリケーション設定を必要なものに上書きします!)