2016-06-20 13 views
26

Mam trochę kodu do przechwytywania treści aplikacji pulpitu systemu Windows i zapisywania do obiektu Bitmap w .NET. Korzysta z User32.dll i Gdi32.dll (BitBlt) i działa dobrze. Jednak kod generuje całkowicie czarne bitmapy, gdy nadaję kodowi uchwyt do okna, w którym znajduje się aplikacja Sklep Windows. Nie jestem pewien, czy to jest funkcja bezpieczeństwa, czy co. Nie mogę używać api ScreenCapture, ponieważ zawartość okna po zmianie rozmiaru jest prawie zawsze wyższa/większa niż ekran. Czy ktoś miał szczęście chwytając zawartość okna, nawet gdy są większe niż ekran, dla aplikacji Windows Store?Jak przechwytywać zawartość okna aplikacji Sklepu Windows w języku C#

EDYCJA: Tak jak w notatce, próbuję uchwycić okno innego programu, a nie własny program. Można założyć, że mój program jest aplikacją Windows Console w .NET 4.6.1/C#

Co więcej, wiem, że musi to być możliwe w interfejsie API Windows, ponieważ funkcja Aero Peek, po najechaniu kursorem na pasek zadań na ikonie uruchomionego programu wyświetla pełną wysokość okna, w tym elementy poza ekranem. (Patrz wysokie okna z prawej strony, zestaw do 6000px znacznie wyższa niż mój wyświetlaczu)

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

+0

I nie można zamknąć w dwóch egzemplarzach, z powodu dobroci, ale widziałeś: [ekran przechwytywania Windows App Store] (http://stackoverflow.com/questions/15883332/capture-screen-of -windows-store-app) –

+0

Czy jesteś właścicielem tej aplikacji? Ponieważ w ogólnym przypadku, jeśli aplikacja ma fragmenty poza ekranem, nic nie może zagwarantować fizycznego renderowania zawartości poza ekranem. W ogólnym przypadku można uchwycić tylko to, co jest wyświetlane na ekranie (np. Za pomocą graphics.CopyFromScreen). –

+0

Nie, nie jestem właścicielem aplikacji. Próbuję przechwycić aplikację sklepu Windows z aplikacji konsoli napisanej w .NET 4.6.1. – Richthofen

Odpowiedz

3

Począwszy od Windows 8.1, można użyć Windows.UI.Xaml.Media.Imaging.RenderTargetBitmap do renderowania elementów do bitmapy. Istnieje kilka zastrzeżeń do tego:

  1. Można uchwycić elementy, które są poza ekranem, tak długo jak są one w drzewie wizualne XAML i mają Visibility zestaw do Visible i nie Collapsed.
  2. Niektóre elementy, takie jak wideo, nie zostaną przechwycone.

Zobacz API więcej szczegółów:

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

+0

Niestety nie mogę użyć RenderTargetBitmap, ponieważ nie mam dostępu do drzewa XAML aplikacji. Uruchamiam przechwytywanie z osobnej aplikacji niż tej, którą próbuję przechwycić. – Richthofen

+0

Ah .. o ile wiem, nie ma sposobu, aby to zrobić. Chciałbym wyjaśnić twoje pytanie, aby było jasne, że próbujesz uchwycić zawartość okna z oddzielnej aplikacji. Życzymy powodzenia - byłoby to dla mnie interesujące, gdyby było to możliwe. –

2

Może to rade. Zasadniczo pobierz uchwyt okna do aplikacji, wywołaj na niej rodzime funkcje, aby określić położenie okna aplikacji, podaj te klasy graficzne i skopiuj je z ekranu.

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

To będzie prawdopodobnie działać w przypadkach, w których potrzebujesz tylko zawartości ekranu. Jednak w moim przypadku moje okno jest większe niż ekran (wysokość ekranu 2000 pikseli, ale wysokość okna/zawartość wynosi około 6000 pikseli). – Richthofen

+0

Podobny do ekranu drukowania selenu (mimo że okno, które próbuję przechwycić nie jest przeglądarką), chcę przechwycić cały bufor zawartości okna za jednym zamachem. – Richthofen

+0

Ah dostałem to. Więc rzeczywiście potrzebujesz wewnętrznej zawartości aplikacji, która wymaga normalnego przewijania, chcesz, aby została ona wyodrębniona do obrazu. –

Powiązane problemy