locked
System.ArgumentException: Parameter is not valid. at System.Drawing.Graphics.GetHdc() RRS feed

  • Question

  •  

    I have a .NET (C#) application that regularly (approx. every 10 seconds) take a screenshot via System.Drawing.Graphics.CopyFromScreen(). This works fine almost all of the time, but once in a while I get this exception:

     

    Code Snippet
    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(Point upperLeftSource, Point upperLeftDestination, Size blockRegionSize, CopyPixelOperation copyPixelOperation)

     

    After this error occurs once then further attempts to capture the screen also fail. I have discovered, however, that if I end the thread that is doing this and restart a new one then it can continue to capture the screen successfully.

     

    The way that I'm creating the Graphics object from which I'm doing the capture is:

     

    Code Snippet

    using(Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppArgb))

    {

    using(Graphics graphics = Graphics.FromImage(bitmap))

    {

    ...my code...

    }

    }

     

    My question is, how can I avoid these problems in the first place?

     

    Any suggestions would be greatly appreciated.

    Monday, June 16, 2008 4:35 AM

Answers

  • There's a bug in the .NET V2.0 SP1 and .NET 3.5 version of CopyFromScreen().  It leaks a handle, after a while you'll run out available handles and get weirdo error messages like this.  You can't use it in its present condition, check this thread for another way to do it by P/Invoking Windows API functions.
    Tuesday, June 17, 2008 12:03 AM

All replies

  • I assume your code is proprietary so you cannot post it.  CopyFromScreen has a memory leak, but at 10 seconds a shot it would take weeks to show up.  Can you explain the purpose of GetDc in your code?  Your code starts off as a standard screenshot.

    Monday, June 16, 2008 8:10 AM
  •  

    Thanks for the reply. Yes our code is proprietary, but this bit is rather straight forward. Basically we scale down the screenshot and save it to disk in JPEG format. I'm pretty sure that's not the root cause.

     

    You mention that CopyFromScreen has a memory leak. Would that leak manifest itself as the ArgumentException that I'm seeing? Also, do you know of anyway to a free up whatever is leaking? As I mentioned, it appears that ending the thread that is doing the screenshot seems to fix the problem, but I'd like a less invasive way to do that if possible.

     

    As for your question, the GetHdc is called from CopyFromScreen, we are not calling it directly.

    Monday, June 16, 2008 11:02 PM
  • There's a bug in the .NET V2.0 SP1 and .NET 3.5 version of CopyFromScreen().  It leaks a handle, after a while you'll run out available handles and get weirdo error messages like this.  You can't use it in its present condition, check this thread for another way to do it by P/Invoking Windows API functions.
    Tuesday, June 17, 2008 12:03 AM