Windows Forms не нужно, это лишнее.
1. Создаю пустое .NET 6 приложение.
2. Устанавливаю NuGet пакет System.Drawing.Common
3. Правлю TargetFramework
проекта на net6.0-windows
, чтобы IDE не ругалась о несовместимости приложения с другими платформами.
В результате .csproj файл выглядит вот так
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
</ItemGroup>
</Project>
4. Разрешение моего монитора 3840x2400, то есть потребуется поддержка мониторов с высоким DPI. Чтобы она появилась, просто вызову метод WinAPI SetProcessDPIAware
, и тогда система будет знать, что мое приложение умеет работать с физическими мониторами с DPI, отличным от 96.
Получается такой код:
using System.Diagnostics;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
namespace ScreenshotGdi;
class Program
{
[DllImport("user32.dll")]
static extern bool SetProcessDPIAware();
static Size GetMonitorSize()
{
IntPtr hwnd = Process.GetCurrentProcess().MainWindowHandle;
using Graphics g = Graphics.FromHwnd(hwnd);
return new Size((int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height);
}
static Bitmap TakeScreenshot(Size size)
{
Bitmap bmp = new Bitmap(size.Width, size.Height);
using Graphics graphics = Graphics.FromImage(bmp);
graphics.CopyFromScreen(Point.Empty, Point.Empty, bmp.Size);
return bmp;
}
static void Main(string[] args)
{
SetProcessDPIAware();
Size monitorSize = GetMonitorSize();
using Bitmap bitmap = TakeScreenshot(monitorSize);
bitmap.Save("img.png", ImageFormat.Png);
}
}
И вот такой скриншот

Делать скриншоты можно еще с помощью DirectX
Вместо вызова WinAPI SetProcessDPIAware
, можно прописать поддержку DPI в манифест.