首页 > 解决方案 > 程序正常运行 24 分钟,然后 GDI+ 中出现一般错误

问题描述

我制作了一个程序来一遍又一遍地截取特定窗口的屏幕截图,并且在执行压力测试时一切正常,直到第 4997 次迭代。

我猜屏幕截图部分的某处有泄漏,但我已尽一切努力防止它发生但无济于事。

这是 Screenshot.cs

    [DllImport("user32.dll")]
    private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rectangle rect);

    [DllImport("gdi32.dll")]
    private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
    [DllImport("gdi32.dll")]
    private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,int nWidth,int nHeight);
    [DllImport("gdi32.dll")]
    private static extern IntPtr SelectObject(IntPtr hdc,IntPtr hgdiobj);
    [DllImport("gdi32.dll")]
    private static extern int DeleteDC(IntPtr hdc);
    [DllImport("user32.dll")]
    private static extern bool PrintWindow(IntPtr hwnd,IntPtr hdcBlt,UInt32 nFlags);
    [DllImport("user32.dll")]
    private static extern IntPtr GetWindowDC(IntPtr hwnd);

    public static Bitmap MakeScreenshotOfWindow(IntPtr hWnd)
    {
        IntPtr hscrdc = GetWindowDC(hWnd);
        Rectangle windowRect = new Rectangle();
        GetWindowRect(hWnd, ref windowRect);
        int width = Math.Abs(windowRect.X - windowRect.Width);
        int height = Math.Abs(windowRect.Y - windowRect.Height);
        IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, width, height);
        IntPtr hmemdc = CreateCompatibleDC(hscrdc);
        SelectObject(hmemdc, hbitmap);
        PrintWindow(hWnd, hmemdc, 0);
        Bitmap bmp = Image.FromHbitmap(hbitmap);
        DeleteDC(hscrdc);
        DeleteDC(hmemdc);
        return bmp;
    }

这是我调用 MakeScreenshotOfWindow 函数的片段:

            using (Bitmap screenShot = Screenshot.MakeScreenshotOfWindow(WindowHandle))
            {
                if (screenShot == null)
                {
                    thumbnailError = "screenShot was null";
                    return false;
                }
                else
                {
                    screenShot.Save($"{Program.thumbnailStorage}\\{assetId}-{assetType}-{t}.png", ImageFormat.Png);
                    screenShot.Dispose();
                }
            }

这是发生的完整异常

System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+.
   at System.Drawing.Image.FromHbitmap(IntPtr hbitmap, IntPtr hpalette)
   at System.Drawing.Image.FromHbitmap(IntPtr hbitmap)
   at ThumbnailServer.Screenshot.PrintWindow(IntPtr hWnd) in C:\Users\darkg\source\repos\ThumbnailServer\ThumbnailServer\Screenshot.cs:line 69
   at ThumbnailServer.ThumbnailGenerator.Click(Int32 t, Int32 assetId, Int32 assetType, String& thumbnailError, Int32 w, Int32 h, Boolean hideSky) in C:\Users\darkg\source\repos\ThumbnailServer\ThumbnailServer\ThumbnailGenerator.cs:line 72

标签: c#

解决方案


我通过添加以下内容来修复它:

[DllImport("gdi32.dll")]
private static extern IntPtr DeleteObject(IntPtr hwnd);

然后这个:

DeleteObject(hbitmap);

推荐阅读