Search code examples
c#screenshotexternal

Screenshot non-active external application


I need to take a screenshot of a non-active external application, for example, TeamSpeak or Skype.

I have searched and i didn't find much, i know that it is not possible to screenshot a minimised application, but i think it should be possible to screenshot a non-active application.

PS : I want to screenshot just the application, so if another application is on top of the one i want, would it be a problem?

I have no code right now, i have found a user32 API that can do what i want but i forgot the name..

Thanks for the help.


Solution

  • The API you're after is PrintWindow:

    void Example()
    {
        IntPtr hwnd = FindWindow(null, "Example.txt - Notepad2");
        CaptureWindow(hwnd);
    }
    
    [DllImport("User32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
    
    [DllImport("user32.dll")]
    static extern bool GetWindowRect(IntPtr handle, ref Rectangle rect);
    
    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
    public void CaptureWindow(IntPtr handle)
    {
        // Get the size of the window to capture
        Rectangle rect = new Rectangle();
        GetWindowRect(handle, ref rect);
    
        // GetWindowRect returns Top/Left and Bottom/Right, so fix it
        rect.Width = rect.Width - rect.X;
        rect.Height = rect.Height - rect.Y;
    
        // Create a bitmap to draw the capture into
        using (Bitmap bitmap = new Bitmap(rect.Width, rect.Height))
        {
            // Use PrintWindow to draw the window into our bitmap
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                IntPtr hdc = g.GetHdc();
                if (!PrintWindow(handle, hdc, 0))
                {
                    int error = Marshal.GetLastWin32Error();
                    var exception = new System.ComponentModel.Win32Exception(error);
                    Debug.WriteLine("ERROR: " + error + ": " + exception.Message);
                    // TODO: Throw the exception?
                }
                g.ReleaseHdc(hdc);
            }
    
            // Save it as a .png just to demo this
            bitmap.Save("Example.png");
        }
    }