Подтвердить что ты не робот

Как захватить содержимое окна приложения Windows Store в С#

У меня есть немного кода для захвата содержимого рабочего стола Windows и сохранения объекта Bitmap в .NET. Он использует User32.dll и Gdi32.dll(BitBlt) и работает отлично. Тем не менее, код создает все-черные растровые изображения, когда я передаю код дескриптору в окно, содержащее приложение Windows Store. Я не уверен, что это функция безопасности или что-то еще. Я не могу использовать ScreenCapture api, поскольку содержимое окна, после изменения размера, почти всегда выше/больше, чем экран. Кто-нибудь успел запечатлеть содержимое окна, даже если он больше экрана, для приложения Windows Store?

EDIT: Как примечание, я пытаюсь захватить другое окно программы, а не свою собственную программу. Моя программа может считаться приложением Windows Console в .NET 4.6.1/С#

Кроме того, я знаю, что это должно быть возможно каким-то образом в Windows API, потому что функция Aero Peek, где, если вы наведите указатель мыши на панель задач на значке текущей программы, отображается полная высота окна, включая внеэкранные компоненты. (см. высокое окно справа, установите на 6000 пикселей намного выше, чем мой дисплей)

увидеть высокое окно справа, установить на 6000 пикселей намного выше, чем мой экран

4b9b3361

Ответ 1

Начиная с Windows 8.1, вы можете использовать Windows.UI.Xaml.Media.Imaging.RenderTargetBitmap для рендеринга элементов в растровое изображение. Есть несколько предостережений:

  • Вы можете захватывать элементы, которые находятся вне экрана, если они находятся в визуальном дереве XAML и имеют Visibility для Visible, а не Collapsed.
  • Некоторые элементы, такие как видео, не будут захвачены.

Подробнее см. API:

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

Ответ 2

Это может сделать трюк. В основном получить дескриптор окна в приложение, вызвать собственные функции на нем, чтобы выяснить положение окна приложения, предоставить им класс графики и скопировать с экрана.

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 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);
    }
}