0

I'm trying to create a c# console application that takes a screenshot of the entire screen, i know this has been asked a bunch of times on SO, but i have a problem with it that i just can't find an answer to.

This is my code:

Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
 g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);
 bmp.Save("screenshot.png");  // saves the image
}

But for some reason I get an error that says

The name 'Screen' does not exist in the current context

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
  • Okay @Josh, do is there anything i can do to take a screenshot from a console application that you know of? – Sebastian Skov Nielsen Jan 14 '20 at 22:19
  • @RufusL I already tested that out and it doesn't work. –  Jan 14 '20 at 22:44
  • @RufusL I tried WriteLine on `Screen.PrimaryScreen.Bounds.Width` and it only writes `X`, when I try to assign the Width to an int it just crashes and stops execution –  Jan 14 '20 at 22:45
  • 1
    @Josh Weird. I just copy/pasted the code above, added a reference to `System.Windows.Forms`, and when I ran it, it took a screenshot and saved it as `"screenshot.png"`. – Rufus L Jan 14 '20 at 22:47
  • Hmm, that's strange. Well if it works for you, I'll delete my comment since it seems to be an issue on my end –  Jan 14 '20 at 22:48

1 Answers1

1

But for some reason i get an error that says, "The name 'Screen' does not exist in the current context"

The reason for this is that the Screen class belongs to the System.Windows.Forms assembly, which is not referenced by default in a Console Application.

To resolve this issue, add a reference to the assembly in your project and then add using System.Windows.Forms to the top of your code file.

To add a reference:

  1. Right-click on your project in the solution Explorer and choose "Add Reference..."
  2. In the Reference Manager window that opens, navigate to Assemblies -> Framework on the left
  3. Scroll down the middle window and check the box next to System.Windows.Forms
  4. Click "OK"

Then add a using statement to your code file, similar to this sample based on your code:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Tests
{
    public class Program
    {
        public static Bitmap TakeScreenshot(string filePath = null)
        {
            var bounds = Screen.PrimaryScreen.Bounds;
            var bmp = new Bitmap(bounds.Width, bounds.Height);

            using (var g = Graphics.FromImage(bmp))
            {
                g.CopyFromScreen(0, 0, 0, 0, bounds.Size);
            }

            if (filePath != null) bmp.Save(filePath);

            return bmp;
        }

        public static void Main()
        {
            Console.WriteLine("Taking a screenshot now...");

            TakeScreenshot("screenshot.bmp");

            Console.WriteLine("\nDone! Press any key to exit...");
            Console.ReadKey();
        }
    }
}

Side note: Many users have more than one monitor these days, so if you want to take a screenshot that captures all the screens, you can create a rectangle that encompasses all screens:

public static Bitmap TakeScreenshot(string filePath = null)
{
    var rect = new Rectangle();

    // Take a screenshot that includes all screens by
    // creating a rectangle that captures all monitors
    foreach (var screen in Screen.AllScreens)
    {
        var bounds = screen.Bounds;
        var width = bounds.X + bounds.Width;
        var height = bounds.Y + bounds.Height;

        if (width > rect.Width) rect.Width = width;
        if (height > rect.Height) rect.Height = height;
    }

    var bmp = new Bitmap(rect.Width, rect.Height);

    using (var g = Graphics.FromImage(bmp))
    {
        g.CopyFromScreen(0, 0, 0, 0, rect.Size);
    }

    if (filePath != null) bmp.Save(filePath);

    return bmp;
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43