Search code examples
c#winapiscreenshot

Get a screenshot of a specific application


I know I can get the screenshot of the entire screen using Graphics.CopyFromScreen(). However, what if I just want the screenshot of a specific application?


Solution

  • Here's some code to get you started:

    public void CaptureApplication(string procName)
    {
        var proc = Process.GetProcessesByName(procName)[0];
        var rect = new User32.Rect();
        User32.GetWindowRect(proc.MainWindowHandle, ref rect);
    
        int width = rect.right - rect.left;
        int height = rect.bottom - rect.top;
    
        var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
        using (Graphics graphics = Graphics.FromImage(bmp))
        {
            graphics.CopyFromScreen(rect.left, rect.top, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy);
        }
    
        bmp.Save("c:\\tmp\\test.png", ImageFormat.Png);
    }
    
    private class User32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct Rect
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }
    
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);
    }
    

    It works, but needs improvement:

    • You may want to use a different mechanism to get the process handle (or at least do some defensive coding)
    • If your target window isn't in the foreground, you'll end up with a screenshot that's the right size/position, but will just be filled with whatever is in the foreground (you probably want to pull the given window into the foreground first)
    • You probably want to do something other than just save the bmp to a temp directory