2016-06-20 28 views
26

Ich habe ein wenig Code, um den Inhalt der Windows-Desktop-App zu erfassen und in einem Bitmap-Objekt in .NET zu speichern. Es verwendet User32.dll und Gdi32.dll (BitBlt) und funktioniert gut. Der Code erzeugt jedoch schwarze Bitmaps, wenn ich dem Code einen Punkt für ein Fenster gebe, das eine Windows Store-App enthält. Ich bin mir nicht sicher, ob dies ein Sicherheitsmerkmal ist oder was. Ich kann die ScreenCapture API nicht verwenden, da der Inhalt des Fensters nach der Größenanpassung fast immer größer/größer als der Bildschirm ist. Hat jemand Glück gehabt, Fensterinhalte zu erfassen, selbst wenn sie größer als der Bildschirm sind, für eine Windows Store App?So erfassen Sie den Fensterinhalt einer Windows Store App in C#

EDIT: Genau wie eine Notiz versuche ich ein anderes Programm Fenster zu erfassen, nicht mein eigenes Programm. Mein Programm kann als eine Windows-Konsole-Anwendung in .NET 4.6.1/C#

angenommen werden Auch weiß ich, dass dies irgendwie in Windows-APIs möglich sein muss, da die Aero Peek-Funktion, wenn Sie den Mauszeiger über die Taskleiste bewegen Auf dem Symbol des laufenden Programms wird die gesamte Höhe des Fensters einschließlich der Offscreen-Komponenten angezeigt. (Siehe hohen Fenster auf der rechten Seite, auf 6000px viel höher als meine Anzeige)

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

+0

Ich kann nicht in der Nähe als Duplikat wegen der Prämie, aber haben Sie gesehen: [Aufnahme-Bildschirm von Windows Store App] (http://stackoverflow.com/questions/15883332/capture-screen-of -windows-store-app) –

+0

Besitzen Sie diese App? Weil im Allgemeinen, wenn eine App Teile außerhalb des Bildschirms hat, kann nichts garantieren, dass das, was außerhalb des Bildschirms ist, physisch gerendert werden kann. Im allgemeinen Fall können Sie nur erfassen, was auf dem Bildschirm angezeigt wird (z. B. mit graphics.CopyFromScreen). –

+0

Nein, ich besitze die App nicht. Ich versuche, die Windows Store App über eine in .NET 4.6.1 geschriebene Konsolenanwendung zu erfassen. – Richthofen

Antwort

3

Ab Windows 8.1 können Sie Windows.UI.Xaml.Media.Imaging.RenderTargetBitmap verwenden Elemente in eine Bitmap zu machen. Es gibt ein paar Einschränkungen dazu:

  1. Sie können Elemente erfassen, die außerhalb des Bildschirms sind, solange sie in der XAML-visuellen Struktur sind und Visibility Set Visible und nicht Collapsed.
  2. Einige Elemente wie Video werden nicht erfasst.

Siehe API für weitere Informationen:

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

+0

Leider kann ich die RenderTargetBitmap nicht verwenden, da ich keinen Zugriff auf den XAML-Baum der App habe. Ich führe das Capture von einer anderen App aus als derjenigen, die ich erfassen möchte. – Richthofen

+0

Ah .. so weit ich weiß, gibt es keine Möglichkeit, dies zu tun. Ich würde Ihre Frage klären, um klarzustellen, dass Sie versuchen, den Fensterinhalt von einer separaten App zu erfassen. Viel Glück - das wäre auch für mich interessant, wenn es möglich ist. –

2

Diese den Trick tun könnte. Im Grunde nehmen Sie den Fenstergriff zur App, rufen Sie die nativen Funktionen darauf auf, um die App-Fensterposition herauszufinden, stellen Sie die Grafikklasse zur Verfügung und kopieren Sie vom Bildschirm.

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

Dies funktioniert wahrscheinlich in Fällen, in denen Sie nur Bildschirminhalt benötigen. In meinem Fall ist mein Fenster jedoch größer als der Bildschirm (Bildschirmhöhe 2000 Pixel, aber die Fensterhöhe/Inhalt ist etwas um 6000 Pixel). – Richthofen

+0

Ähnlich wie Selens Druckbildschirm (obwohl das Fenster, das ich erfassen möchte, kein Webbrowser ist), möchte ich den gesamten Puffer von Fensterinhalten auf einmal erfassen. – Richthofen

+0

Ah hat es. Sie benötigen also den inneren Inhalt der App, der normal gescrollt werden muss, und Sie möchten, dass diese in ein Bild extrahiert wird. –