Elmue Elmue - 3 months ago 54
C# Question

Graphics.CopyFromScreen() and GetDC(0) fail with "The handle is invalid"

I have an application that takes screenshots from the local computer.
This works since many years correctly until suddenly a colleague reported me that he got an "The handle is invalid" error from my application.

This error came from inside the .NET framework from

Graphics.CopyFromScreen()
.

To work around this I replaced this function with C++ code using
GetDC(GetDesktopWindow())
/
GetDC(NULL)
and
BitBlt()
to copy the screen into a bitmap. Now I got
ERROR_INVALID_HANDLE
.

This happens on Windows 7.

What is going on there ?
I can not investigate this problem on my own because I cannot reproduce it and my colleague is in another country.

I searched in Google and lots of people report this error.
But all posts that I found were from people who tried to take a screenshot from a client computer through ASP code on a server. I don't understand how people can have the strange desire to capture the client's computer from a website. It is obvious that this will not work.

But I could not find one single case where someone reports this problem from an application that cannot capture the screen of the SAME computer in the SAME session where the application itself is running.

Answer

After investigating more with my colleague and giving him ideas what he can try, he told me that he starts my application through a remote desktop session.

The remote desktop session creates a virtual desktop (you see for example that the desktop wallpaper is missing).

I told my colleague to install a VNC client to remote control the computer instead of a remote desktop session and now all works fine. He installed TightVNC which uses the REAL desktop user session instead of creating a virtual session and locking the screen of the machine.

So if anyone gets reports of "The handle is invalid" while taking a screen capture, ask your users if they use a remote desktop session.

To detect a remote desktop session in code you can write:

in C++:

if (GetSystemMetrics(SM_REMOTESESSION) > 0)
{
    MessageBox(m_hWnd, L"This application may not work correctly in a remote desktop session", "Error", MB_ICONSTOP);
}

or in C#:

if (System.Windows.Forms.SystemInformation.TerminalServerSession)
{
    Messagebox.Show("This application may not work correctly in a remote desktop session");
}

Note that the problem is not reproducible on all computers. When I test on my own Windows 7 it works. So there are probably any additional system settings or other factors that trigger the "The handle is invalid" error (service packs / hotfixes...?).

But my colleague reports that he has never seen the error again after he stopped using the remote desktop connection.