Capture a screenshot of a newly created desktop not working win api

65 Views Asked by At
using System.Diagnostics;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Windows.Media.Imaging;

internal class Program
{
    private static void Main(string[] args)
    {
        ProcessStartInfo ps = new ProcessStartInfo()
        {
            UseShellExecute = false,
            RedirectStandardInput = true,
            FileName = "notepad.exe"
        };

        IntPtr desktopHandle = CreateDesktopExW("abcdesktop", null, IntPtr.Zero, 0, access, IntPtr.Zero, 1000, IntPtr.Zero);

        if(desktopHandle == IntPtr.Zero)
        {
            MessageBox.Show(GetLastError().ToString());
            return;
        }

        if (!SetThreadDesktop(desktopHandle))
        {
            MessageBox.Show(GetLastError().ToString());
            return;
        }

        using (Process notepad = Process.Start(ps))
        {
            notepad.StandardInput.Write("Hi");
            TakeScreenShot();
        }

        Task.Delay(10000).Wait();

        if (!CloseDesktop(desktopHandle))
        {
            MessageBox.Show(GetLastError().ToString());
            return;
        }

        if (!SetThreadDesktop(IntPtr.Zero))
        {
            MessageBox.Show(GetLastError().ToString());
            return;
        }

        MessageBox.Show("Test succeeded!");
    }

    static void TakeScreenShot()
    {
        // Get the device context of the entire screen
        IntPtr hScreenDC = GetDC(IntPtr.Zero);

        // Define the width and height of the screenshot
        int width = Screen.PrimaryScreen.Bounds.Width;
        int height = Screen.PrimaryScreen.Bounds.Height;

        // Create a compatible bitmap
        using (Bitmap bitmap = new Bitmap(width, height))
        {
            // Create a Graphics object associated with the screen device context
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                // Capture the screen
                graphics.CopyFromScreen(0, 0, 0, 0, new Size(width, height));
            }

            // Save the captured image
            bitmap.Save(Path.Combine(Directory.GetCurrentDirectory(), "ScreenShot.png"), ImageFormat.Png);
        }

        // Release the device context
        ReleaseDC(IntPtr.Zero, hScreenDC);
    }

    #region dllImports

    //https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createdesktopexw
    [DllImport("user32.dll")]
    static extern IntPtr CreateDesktopExW(
        [MarshalAs(UnmanagedType.LPWStr)] string lpszDesktop,
        [MarshalAs(UnmanagedType.LPWStr)] string lpszDevice,
        IntPtr pDevmode,
        UInt32 dwFlags,
        UInt32 dwDesiredAccess,
        IntPtr lpsa,
        UInt32 ulHeapSize,
        IntPtr pvoid
        );

    //https://learn.microsoft.com/en-us/windows/win32/winstation/desktop-security-and-access-rights
    static UInt32 access = (UInt32)(0x0004L | 0x0002L | 0x0040L | 0x0008L | 0x0020L | 0x0010L | 0x0001L | 0x0100L | 0x0080L);

    [DllImport("user32.dll")]
    static extern bool CloseDesktop(IntPtr hDesktop);

    [DllImport("kernel32.dll")]
    public static extern uint GetLastError();

    //https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setthreaddesktop
    [DllImport("user32.dll")]
    static extern bool SetThreadDesktop(IntPtr hDesktop);


    [DllImport("user32.dll")]
    public static extern IntPtr GetDC(IntPtr hWnd);

    [DllImport("user32.dll")]
    public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

    [DllImport("user32.dll")]
    static extern bool SwitchDesktop(IntPtr hDesktop);

    #endregion
}

I've checked every return and nothing seems to fail except when the screenshot method runs, it seems like it fails because I've made the calling process run on the newly created desktop thread. "Invalid handle" I get on the g.CopyFromScreen sequence.

I also experimented with SwitchDesktop, and it seems like if I switch desktop my screen returns blank.

Why could this be?

0

There are 0 best solutions below