2016-10-12 5 views
0

Я пытаюсь сохранить скриншот всех открытых окон на windows 7.Скриншот всех открытых окон

Проблема в том, что вместо получения снимков экрана открытых окон это дает мне cmd.exe скриншот. (Например, вместо того, чтобы делать снимок экрана Google Chrome, он показывает черный снимок экрана cmd.exe).

Я пробовал один и тот же код на окнах 10 раньше и, казалось, работал.

Я использовал следующий код из http://www.developerfusion.com/code/4630/capture-a-screen-shot/, чтобы получить скриншот конкретного окна.

namespace ScreenShotDemo 
{ 
    /// <summary> 
    /// Provides functions to capture the entire screen, or a particular window, and save it to a file. 
    /// </summary> 
    public class ScreenCapture 
    { 
     /// <summary> 
     /// Creates an Image object containing a screen shot of the entire desktop 
     /// </summary> 
     /// <returns></returns> 
     public Image CaptureScreen() 
     { 
      return CaptureWindow(User32.GetDesktopWindow()); 
     } 
     /// <summary> 
     /// Creates an Image object containing a screen shot of a specific window 
     /// </summary> 
     /// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param> 
     /// <returns></returns> 
     public Image CaptureWindow(IntPtr handle) 
     { 
      // get te hDC of the target window 
      IntPtr hdcSrc = User32.GetWindowDC(handle); 
      // get the size 
      //User32.RECT windowRect = new User32.RECT(); 
      //User32.GetWindowRect(handle, ref windowRect); 
      //int width = windowRect.right - windowRect.left; 
      //int height = windowRect.bottom - windowRect.top; 

      User32.WINDOWINFO info = new User32.WINDOWINFO(); 
      User32.GetWindowInfo(handle, ref info); 
      int width = info.rcWindow.right - info.rcWindow.left; 
      int height = info.rcWindow.bottom - info.rcWindow.top; 

      // create a device context we can copy to 
      IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc); 
      // create a bitmap we can copy it to, 
      // using GetDeviceCaps to get the width/height 
      IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height); 
      // select the bitmap object 
      IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap); 
      // bitblt over 
      GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY); 
      // restore selection 
      GDI32.SelectObject(hdcDest, hOld); 
      // clean up 
      GDI32.DeleteDC(hdcDest); 
      User32.ReleaseDC(handle, hdcSrc); 
      // get a .NET image object for it 
      Image img = Image.FromHbitmap(hBitmap); 
      // free up the Bitmap object 
      GDI32.DeleteObject(hBitmap); 
      return img; 
     } 
     /// <summary> 
     /// Captures a screen shot of a specific window, and saves it to a file 
     /// </summary> 
     /// <param name="handle"></param> 
     /// <param name="filename"></param> 
     /// <param name="format"></param> 
     public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format) 
     { 
      Image img = CaptureWindow(handle); 
      img.Save(filename, format); 
     } 
     /// <summary> 
     /// Captures a screen shot of the entire desktop, and saves it to a file 
     /// </summary> 
     /// <param name="filename"></param> 
     /// <param name="format"></param> 
     public void CaptureScreenToFile(string filename, ImageFormat format) 
     { 
      Image img = CaptureScreen(); 
      img.Save(filename, format); 
     } 

     /// <summary> 
     /// Helper class containing Gdi32 API functions 
     /// </summary> 
     private class GDI32 
     { 

      public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter 
      [DllImport("gdi32.dll")] 
      public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, 
       int nWidth, int nHeight, IntPtr hObjectSource, 
       int nXSrc, int nYSrc, int dwRop); 
      [DllImport("gdi32.dll")] 
      public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, 
       int nHeight); 
      [DllImport("gdi32.dll")] 
      public static extern IntPtr CreateCompatibleDC(IntPtr hDC); 
      [DllImport("gdi32.dll")] 
      public static extern bool DeleteDC(IntPtr hDC); 
      [DllImport("gdi32.dll")] 
      public static extern bool DeleteObject(IntPtr hObject); 
      [DllImport("gdi32.dll")] 
      public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); 
     } 

     /// <summary> 
     /// Helper class containing User32 API functions 
     /// </summary> 
     private class User32 
     { 
      [StructLayout(LayoutKind.Sequential)] 
      public struct RECT 
      { 
       public int left; 
       public int top; 
       public int right; 
       public int bottom; 
      } 
      [DllImport("user32.dll")] 
      public static extern IntPtr GetDesktopWindow(); 
      [DllImport("user32.dll")] 
      public static extern IntPtr GetWindowDC(IntPtr hWnd); 
      [DllImport("user32.dll")] 
      public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC); 
      [DllImport("user32.dll")] 
      public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect); 

      [DllImport("user32.dll")] 
      public static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi); 

      [StructLayout(LayoutKind.Sequential)] 
      public struct WINDOWINFO 
      { 
       public uint cbSize; 
       public RECT rcWindow; 
       public RECT rcClient; 
       public uint dwStyle; 
       public uint dwExStyle; 
       public uint dwWindowStatus; 
       public uint cxWindowBorders; 
       public uint cyWindowBorders; 
       public ushort atomWindowType; 
       public ushort wCreatorVersion; 

       public WINDOWINFO(Boolean? filler) 
       : this() // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)". 
       { 
        cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO))); 
       } 

      } 

     } 
    } 
} 

Чтобы получить список открытых окон, я использую следующий код.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Threading.Tasks; 

using HWND = System.IntPtr; 

/// <summary>Contains functionality to get all the open windows.</summary> 
public static class OpenWindowGetter 
{ 
    /// <summary>Returns a dictionary that contains the handle and title of all the open windows.</summary> 
    /// <returns>A dictionary that contains the handle and title of all the open windows.</returns> 
    public static IDictionary<HWND, string> GetOpenWindows() 
    { 
     HWND shellWindow = GetShellWindow(); 
     Dictionary<HWND, string> windows = new Dictionary<HWND, string>(); 

     EnumWindows(delegate (HWND hWnd, int lParam) 
     { 
      if (hWnd == shellWindow) return true; 
      if (!IsWindowVisible(hWnd)) return true; 

      int length = GetWindowTextLength(hWnd); 
      if (length == 0) return true; 

      StringBuilder builder = new StringBuilder(length); 
      GetWindowText(hWnd, builder, length + 1); 

      windows[hWnd] = builder.ToString(); 
      return true; 

     }, 0); 

     return windows; 
    } 

    private delegate bool EnumWindowsProc(HWND hWnd, int lParam); 

    [DllImport("USER32.DLL")] 
    private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); 

    [DllImport("USER32.DLL")] 
    private static extern int GetWindowText(HWND hWnd, StringBuilder lpString, int nMaxCount); 

    [DllImport("USER32.DLL")] 
    private static extern int GetWindowTextLength(HWND hWnd); 

    [DllImport("USER32.DLL")] 
    private static extern bool IsWindowVisible(HWND hWnd); 

    [DllImport("USER32.DLL")] 
    private static extern IntPtr GetShellWindow(); 
} 

Ниже приводится Main класс

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using ScreenShotDemo; 
using System.Drawing.Imaging; 

namespace ScreenCaptureTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      long start = DateTime.Now.Millisecond; 
      captureAllWindowsToFile(); 
      //captureAllWindowsToFile2(); 
      //captureDesktopToFile(); 
      long end = DateTime.Now.Millisecond; 

      Console.WriteLine("time taken: " + (end - start)); 
      //Console.Read(); 
     } 

     static void captureAllWindowsToFile() 
     { 
      IDictionary<IntPtr, string> windowDict = OpenWindowGetter.GetOpenWindows(); 

      ScreenCapture sc = new ScreenCapture(); 
      int captureI = 0; 
      string message = ""; 
      foreach(KeyValuePair<IntPtr, string> window in windowDict) 
      { 
       string imageName = "test" + ++captureI + ".jpg"; 
       message +=imageName + " : " + window.Value + "\n"; 
       sc.CaptureWindowToFile(window.Key, imageName, ImageFormat.Jpeg); 
      } 
      Console.WriteLine(message); 
     } 

     static void captureDesktopToFile() 
     { 
      ScreenCapture sc = new ScreenCapture(); 
      sc.CaptureScreenToFile("current.jpg", ImageFormat.Jpeg); 
     } 
    } 
} 

Любая помощь приветствуется.

ответ

0

Я, наконец, нашел проблему.

Я изменил настройки Windows 7 для лучшей производительности, как только я изменил его на обычные настройки Aero. Он работает так, как ожидалось.

Смежные вопросы