在.NET中截取屏幕截图后出现运行时错误

时间:2011-07-22 09:46:20

标签: c# .net

给出以下代码

 public static Bitmap PrintWindow(IntPtr hWnd)
    {
        int width = GetWindowInfo(hWnd).rcWindow.Width;
        int height =  GetWindowInfo(hWnd).rcWindow.Height;
        Logger.log("width and height: " + width + "," + height, 0);
        Bitmap bmp = new Bitmap(width, height);
        Graphics memoryGraphics = Graphics.FromImage(bmp);
        memoryGraphics.CopyFromScreen(0, 0, 0, 0, GetWindowInfo(hWnd).rcWindow.Size);
        return bmp;
    }

我的应用程序需要大量的屏幕截图才能进行屏幕抓取。所以这个方法大约每3秒调用一次。它总是很好,但过了一段时间我在这里得到例外。如果我构建了容错(仅在异常时重试)它会继续运行,但我的日志会显示许多失败的尝试。

以下是3个例外:

Exception caught : System.ComponentModel.Win32Exception (0x80004005): The parameter is incorrect
at System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX, Int32 destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation)
   at System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX, Int32 destinationY, Size blockRegionSize)
   at MoonHandler.scraping.User32Facade.PrintWindow(IntPtr hWnd) in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\User32Facade.cs:line 50
   at MoonHandler.scraping.MoonFacade.getBMP(Boolean fresh) in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\MoonFacade.cs:line 37
   at MoonHandler.scraping.MoonFacade.isWarpDriveActive() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\MoonFacade.cs:line 154
   at MoonHandler.logic.MoonLogic.warping_to_belt() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\logic\MoonLogic.cs:line 113
   at MoonHandler.logic.MoonLogic.act() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\logic\MoonLogic.cs:line 47

Exception caught : System.ArgumentException: Parameter is not valid.
   at System.Drawing.Graphics.GetHdc()
   at System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX, Int32 destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation)
   at System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX, Int32 destinationY, Size blockRegionSize)
   at MoonHandler.scraping.User32Facade.PrintWindow(IntPtr hWnd) in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\User32Facade.cs:line 50
   at MoonHandler.scraping.MoonFacade.getBMP(Boolean fresh) in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\MoonFacade.cs:line 37
   at MoonHandler.scraping.MoonFacade.isWarpDriveActive() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\MoonFacade.cs:line 154
   at MoonHandler.logic.MoonLogic.warping_to_belt() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\logic\MoonLogic.cs:line 113
   at MoonHandler.logic.MoonLogic.act() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\logic\MoonLogic.cs:line 47

Exception caught : System.ArgumentException: Parameter is not valid.
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)
   at MoonHandler.scraping.User32Facade.PrintWindow(IntPtr hWnd) in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\User32Facade.cs:line 48
   at MoonHandler.scraping.MoonFacade.getBMP(Boolean fresh) in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\MoonFacade.cs:line 37
   at MoonHandler.scraping.MoonFacade.isWarpDriveActive() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\scraping\MoonFacade.cs:line 154
   at MoonHandler.logic.MoonLogic.warping_to_belt() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\logic\MoonLogic.cs:line 113
   at MoonHandler.logic.MoonLogic.act() in d:\users\npiv\documents\visual studio 2010\Projects\MoonMiner\ConsoleApplication2\logic\MoonLogic.cs:line 47

我意识到这些是3个不同的例外,但我觉得它们是相互联系的。因为它只是在运行时开始发生,这是某种内存泄漏吗?我可以用另一种方式拍摄屏幕吗?

3 个答案:

答案 0 :(得分:4)

试试这个:

public static Bitmap PrintWindow(IntPtr hWnd)
{
    sleep();
    int width = GetWindowInfo(hWnd).rcWindow.Width;
    int height =  GetWindowInfo(hWnd).rcWindow.Height;
    Logger.log("width and height: " + width + "," + height, 0);
    Bitmap bmp = new Bitmap(width, height);

    using (Graphics memoryGraphics = Graphics.FromImage(bmp))
        memoryGraphics.CopyFromScreen(0, 0, 0, 0, GetWindowInfo(hWnd).rcWindow.Size);

    return bmp;
}

答案 1 :(得分:2)

我可能错了,但System.Drawing.Graphics和System.Drawing.Bitmap实现了IDisposable。它与GDI资源一起使用的事实让我觉得你有资源泄漏......

(考虑到那种语言,我从来没有发现过有趣的事情,但是我不喜欢)

无论如何,您应该考虑处置GraphicsBitmap个对象。

类似的东西:

public static Bitmap PrintWindow(IntPtr hWnd)
{
    int width = GetWindowInfo(hWnd).rcWindow.Width;
    int height =  GetWindowInfo(hWnd).rcWindow.Height;
    Logger.log("width and height: " + width + "," + height, 0);

    Bitmap bmp = new Bitmap(width, height);

    // the following line will make sure memoryGraphics
    // will be disposed nicely.
    using(Graphics memoryGraphics = Graphics.FromImage(bmp))
    {
       memoryGraphics.CopyFromScreen(0, 0, 0, 0, GetWindowInfo(hWnd).rcWindow.Size);
    }

    return bmp;
} // And don't forget to dispose of Bitmap when not used anymore !!!
  // call: bmp.Dispose() once you don't need it anymore.

来源:

答案 2 :(得分:1)

派对的时间已经很晚了,但万一有人(像我一样)偶然发现这些错误试图进行C#屏幕捕获:

  1. “参数无效。”在Bitmap ctor 中,我试图传递一个空的coords(由于我在已经关闭的窗口的hWnd上调用了GetClientRect,因为它是空的)。

  2. “System.ComponentModel.Win32Exception(0x80004005):当没有主桌面可见时,CopyFromScreen中的参数不正确” - 例如,在服务模式下,或(在我的情况下) )当用户在Windows 7/8中按“Ctrl-Alt-Del”时。

  3. 希望这有助于某人。 ;)