Take screenshot of any external application using

2019-07-01 10:21发布

问题:

We have a C# (WPF) application in which we want to take a screenshot of an arbitrary application launched by us (i.e. so we have a reference to the Process we started). The application may be minimized or behind other windows but we still only want the image of the individual application, not overlapping pixels.

I know the typical P/Invoke solutions using BitBlt or PrintWindow work most of the time, but those fail (I only get black/transparent pixels) when dealing with an DirectX or OpenGL application that draws directly to the graphics device. I have found this article on taking a screenshot of a Direct3D app from C#, so I think I have that case covered.

So my question is this:

  1. How would I do this for an OpenGL application?
  2. What is the easiest way to determine the appropriate method to use (PW/DX/GL)?
  3. Is there a single universal way of doing this?

For #2, am I relegated to inspecting the modules loaded by the executable and seeing if an DirectX or OpenGL DLL/Assembly is loaded?

This only has to run on Windows XP (not cross-platform and not going to Vista/7 anytime soon if ever for this application).

回答1:

Answer to 1: In OpenGL, you can call glReadBuffer and glReadPixels to get the screen bitmap. However, this is slow (so you don't call it repeatedly every frame) and you might also have problems when th GL window is overlapped by another application / window. The correct way to do this is to "render to texture" (google it) by using a pbuffer.

Idea for 2: If you have the handle to window, you might be able to get the pixelformatdescriptor structure it has and check it. Never tried it though.

For 3: By the way, I don't think there is a single universal way of doing this without any problems..