Windows Form: Cattura dello schermo quando non si esegue graficamente (ovvero lo screensaver è attivo)

StackOverflow https://stackoverflow.com/questions/183118

  •  06-07-2019
  •  | 
  •  

Domanda

Ho un'applicazione che usa molta grafica e si basa su DirectX e Windows Forms. Ha un framework di automazione e replay attorno al quale è costruito un sistema di test automatizzato. Sfortunatamente, quando i test vengono eseguiti incustoditi durante una build notturna, il display è inattivo o collegato allo screensaver e le nostre politiche di sicurezza IT non ci consentono di disabilitarlo.

Quindi la mia domanda: c'è un modo per fare uno "schermo"? acquisizione di un'applicazione in esecuzione senza display? Vorrei assicurarmi che la scheda grafica sia impegnata in modo che la mia pipeline di rendering sia la stessa, ma il framework di test non dovrebbe occuparsi dello stato del display.

Qualsiasi aiuto è stato molto apprezzato!

È stato utile?

Soluzione

Dato che hai menzionato la pipeline di rendering, quindi suppongo che tu stia usando Direct3d, in tal caso, puoi salvare il backbuffer del frame. L'ho fatto quando stavo ancora usando VB.Net + MDX

Dim tempSurface As Direct3D.Surface
tempSurface = device.GetBackBuffer(0, 0, Direct3D.BackBufferType.Mono)
Direct3D.SurfaceLoader.Save(tempFilename, Direct3D.ImageFileFormat.Png, tempSurface)

Puoi facilmente convertire qualsiasi linguaggio di programmazione di tua scelta, in pratica chiama l'API di Direct3d. Tuttavia, è necessario configurare il backbuffer e i parametri Present come

' Need to use flip to enable screen capture
presentParams.SwapEffect = Direct3D.SwapEffect.Flip 
presentParams.PresentationInterval = Direct3D.PresentInterval.One

Altri suggerimenti

Installa una VM ed esegui l'applicazione in quella. Se stai eseguendo uno screen saver, dubito che la tua scheda video stia persino generando la GUI per l'applicazione.

Se ho capito bene, tutto quello che vuoi fare è prendere uno screenshot di un'applicazione specifica e non avere il risultato influenzato da uno screensaver in esecuzione? Per quanto ne so, semplicemente fare GetDIBits sull'HDC della finestra corretta dovrebbe fare il trucco e non preoccuparsi dello screensaver.

È possibile che questo codice sia molto lento, tuttavia è possibile ottenere un enorme aumento di velocità impostando PresentParams.PresentFlag = PresentFlag.LockableBackBuffer

Inoltre, non è necessario impostare PresentInterval.One o SwapEffect.Flip , possono essere lasciati su .Default e .Discard ripetutamente.

(Nota che questo speedup non funziona se stai usando il multicampionamento, assicurati che PresentParams.Multisample = Multisample.None . Se hai una scheda Nvidia puoi comunque ottenere l'antialiasing impostando l'opzione nel pannello di controllo di Nvidia per sovrascrivere le impostazioni dell'applicazione su ciò che vuoi!)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top