2016-06-20 7 views
26

Ho un po 'di codice per acquisire il contenuto dell'app desktop di Windows e salvarlo su un oggetto Bitmap in .NET. Usa User32.dll e Gdi32.dll (BitBlt) e funziona bene. Tuttavia, il codice produce bitmap completamente nere quando fornisco al codice un handle per una finestra che contiene un'app di Windows Store. Non sono sicuro se questa è una funzione di sicurezza o cosa. Non riesco ad usare l'API ScreenCapture poiché i contenuti della finestra, dopo essere stati ridimensionati, sono quasi sempre più alti/più grandi dello schermo. Qualcuno ha avuto fortuna a catturare i contenuti di una finestra anche quando sono più grandi dello schermo, per un'app di Windows Store?Come acquisire il contenuto della finestra di un'app di Windows Store in C#

EDIT: Come nota, sto provando a catturare una finestra di un programma diverso, non il mio programma. Il mio programma può essere considerato un'applicazione di console di Windows in .NET 4.6.1/C#

Inoltre, so che questo deve essere possibile in qualche modo nelle API di Windows, perché la funzionalità Aero Peek, dove se si passa il mouse sopra la barra delle applicazioni sull'icona del programma in esecuzione mostra l'intera altezza della finestra, compresi i componenti fuori schermo. (Vedi finestra alta a destra, insieme a 6000px molto più alto di mio display)

see tall window on right, set to 6000px much higher than my display

+0

posso non si chiude come un duplicato a causa della generosità, ma hai visto: [cattura dello schermo di Windows Store App] (http://stackoverflow.com/questions/15883332/capture-screen-of -windows-store-app) –

+0

Possiedi quella app? Perché nel caso generale, se un'app ha parti disattivate sullo schermo, nulla può garantire che ciò che è fuori schermo possa essere reso fisicamente. Nel caso generale, puoi solo catturare ciò che viene visualizzato sullo schermo (con graphics.CopyFromScreen ad esempio). –

+0

No, non possiedo l'app. Sto cercando di acquisire l'app di Windows Store da un'applicazione console scritta in .NET 4.6.1. – Richthofen

risposta

3

partire da Windows 8.1, è possibile utilizzare Windows.UI.Xaml.Media.Imaging.RenderTargetBitmap per rendere gli elementi di una bitmap. Ci sono un paio di avvertimenti a questo:

  1. È possibile catturare elementi che sono fuori dallo schermo, purché siano in albero visuale XAML e hanno Visibility set per Visible e non Collapsed.
  2. Alcuni elementi, come il video, non verranno catturati.

Vedi l'API per maggiori dettagli:

https://msdn.microsoft.com/library/windows/apps/xaml/windows.ui.xaml.media.imaging.rendertargetbitmap.aspx

+0

Purtroppo non riesco a utilizzare RenderTargetBitmap perché non ho accesso all'albero XAML dell'app. Sto eseguendo l'acquisizione da un'app separata rispetto a quella che sto cercando di acquisire. – Richthofen

+0

Ah .. per quanto ne so non c'è modo di farlo. Vorrei chiarire la tua domanda per chiarire che stai cercando di acquisire i contenuti della finestra da un'app separata. Buona fortuna però - questo sarebbe interessante per me anche se è possibile. –

2

Questo potrebbe fare il trucco. Prendi in pratica l'handle della finestra sull'app, chiama le funzioni native su di esso per capire la posizione della finestra dell'app, fornisci a chi fa la classe grafica e copia dallo schermo.

class Program 
{ 
    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern IntPtr FindWindow(string strClassName, string strWindowName); 

    [DllImport("user32.dll")] 
    public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle); 

    public struct Rect 
    { 
     public int Left { get; set; } 
     public int Top { get; set; } 
     public int Right { get; set; } 
     public int Bottom { get; set; } 
    } 


    static void Main(string[] args) 
    { 
     /// Give this your app's process name. 
     Process[] processes = Process.GetProcessesByName("yourapp"); 
     Process lol = processes[0]; 
     IntPtr ptr = lol.MainWindowHandle; 
     Rect AppRect = new Rect(); 
     GetWindowRect(ptr, ref AppRect); 
     Rectangle rect = new Rectangle(AppRect.Left, AppRect.Top, (AppRect.Right - AppRect.Left), (AppRect.Bottom - AppRect.Top)); 
     Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb); 
     Graphics g = Graphics.FromImage(bmp); 
     g.CopyFromScreen(rect.Left, rect.Top, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy); 

     // make sure temp directory is there or it will throw. 
     bmp.Save(@"c:\temp\test.jpg", ImageFormat.Jpeg); 
    } 
} 
+0

Quindi, questo probabilmente funzionerà nei casi in cui è necessario solo il contenuto dello schermo. Tuttavia nel mio caso la mia finestra è più grande dello schermo (altezza dello schermo di 2000 pixel ma l'altezza/contenuto della finestra è qualcosa di circa 6000 pixel). – Richthofen

+0

Simile allo schermo di stampa del selenio (sebbene la finestra che sto tentando di acquisire non sia un browser Web) Voglio catturare l'intero buffer dei contenuti della finestra in un colpo solo. – Richthofen

+0

Ah capito. Quindi hai effettivamente bisogno del contenuto interno dell'app che ha bisogno di scorrere normalmente, vuoi che sia estratto in un'immagine. –

Problemi correlati