在.net中截屏后出现运行时错误

本文关键字:运行时错误 net | 更新日期: 2023-09-27 18:03:24

给定以下代码

 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

我知道这是三个不同的例外,但我觉得它们是有联系的。因为它只在运行时开始发生,这是某种内存泄漏吗?我可以用另一种方式截屏吗?

在.net中截屏后出现运行时错误

试试这个:

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

我可能错了,但是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.

来源:

  • http://msdn.microsoft.com/en-us/library/system.drawing.graphics.aspx
  • http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx
  • http://msdn.microsoft.com/en-us/library/system.drawing.image.aspx

有点晚了,但只是以防有人(像我一样)在尝试做c#屏幕捕获时遇到这些错误:

  1. "参数无效"在位图函数发生时,我试图传递一个空的坐标(这是空的,因为我在已经关闭的窗口的hWnd上调用GetClientRect)。

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

希望这能帮助到别人。div;)