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
}
我检查了每个返回,似乎没有任何失败,除了屏幕截图方法运行时,它似乎失败了,因为我已经使调用进程在新创建的桌面线程上运行。我在
g.CopyFromScreen
序列上得到“无效句柄”。
我还尝试了 SwitchDesktop,似乎如果我切换桌面,我的屏幕就会返回空白。
为什么会这样?
这是个好问题!我也很想知道如何修复这个错误,因为我也遇到了同样的错误。