截取所有可见应用程序和表单的多个桌面的屏幕截图

我正在使用一个具有4个输出(监视器)的系统,每个输出具有1280×1024像素。 我需要整个桌面和所有打开的应用程序的屏幕截图。

我尝试了GetDesktopWindow() (MSDN),但它无法正常工作。 某些表单未显示在捕获的图片上。

我尝试了GetDesktopWindow()函数,但它无法正常工作。

当然不是。

GetDesktopWindow函数返回桌面窗口的句柄 。 它与捕获该窗口的图像没有任何关系。

此外,桌面窗口与“整个屏幕”不同。 它特指桌面窗口。 有关更多信息以及滥用此函数返回的句柄时可能出现的问题,请参阅此文章 。

我正在使用一个系统,每个输出有4个输出(显示器)和1280×1024(例如)。 我需要整个桌面和所有打开的应用程序的截图。

使用Graphics.CopyFromScreen方法在.NET Framework中执行此操作相对简单。 你甚至不需要做任何P / Invoke!

在这种情况下唯一的技巧是确保您传递适当的尺寸。 由于您有4个显示器,因此仅传递主屏幕的尺寸将不起作用。 您需要传递整个虚拟屏幕的尺寸,其中包含所有显示器。 通过查询SystemInformation.VirtualScreen属性来检索它,该属性返回虚拟屏幕的边界。 如文档所示,这是多监视器系统上整个桌面的界限。

示例代码:

 // Determine the size of the "virtual screen", which includes all monitors. int screenLeft = SystemInformation.VirtualScreen.Left; int screenTop = SystemInformation.VirtualScreen.Top; int screenWidth = SystemInformation.VirtualScreen.Width; int screenHeight = SystemInformation.VirtualScreen.Height; // Create a bitmap of the appropriate size to receive the screenshot. using (Bitmap bmp = new Bitmap(screenWidth, screenHeight)) { // Draw the screenshot into our bitmap. using (Graphics g = Graphics.FromImage(bmp)) { g.CopyFromScreen(screenLeft, screenTop, 0, 0, bmp.Size); } // Do something with the Bitmap here, like save it to a file: bmp.Save(savePath, ImageFormat.Jpeg); } 

编辑:

请在一个不是主线程的线程中使用wpf应用程序检查您的解决方案。 我尝试过这个。 它不起作用!

嗯,我没有在问题上看到WPF标签或在身体的任何地方提到过。

不过,无论如何。 我发布的代码在WPF应用程序中运行得很好,只要添加适当的引用并使用声明即可。 您将需要System.Windows.FormsSystem.Drawing 。 可能有更多的WPF方式这样做,不需要依赖这些WinForms程序集,但我不知道它是什么。

它甚至适用于另一个线程。 这里没有任何东西需要UI线程。

是的,我测试了它。 这是我的完整测试代码:

 using System.Windows; using System.Windows.Forms; // also requires a reference to this assembly using System.Drawing; // also requires a reference to this assembly using System.Drawing.Imaging; using System.Threading; public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { // Create a new thread for demonstration purposes. Thread thread = new Thread(() => { // Determine the size of the "virtual screen", which includes all monitors. int screenLeft = SystemInformation.VirtualScreen.Left; int screenTop = SystemInformation.VirtualScreen.Top; int screenWidth = SystemInformation.VirtualScreen.Width; int screenHeight = SystemInformation.VirtualScreen.Height; // Create a bitmap of the appropriate size to receive the screenshot. using (Bitmap bmp = new Bitmap(screenWidth, screenHeight)) { // Draw the screenshot into our bitmap. using (Graphics g = Graphics.FromImage(bmp)) { g.CopyFromScreen(screenLeft, screenTop, 0, 0, bmp.Size); } // Do something with the Bitmap here, like save it to a file: bmp.Save("G:\\TestImage.jpg", ImageFormat.Jpeg); } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } }