×

# C# 切换桌面,切换会话,以安全会话截屏和模拟键盘

hqy hqy 发表于2026-04-08 16:54:10 浏览4 评论0

抢沙发发表评论

# C# 切换桌面,切换会话,以安全会话截屏和模拟键盘

提权之后,就可以切换桌面,切换会话,实现登录界面截图和模拟键盘了

以SharpDX截屏为例

1、切换桌面定义

C#
[Flags]public enum ACCESS_MASK : uint{    DELETE = 0x00010000,    READ_CONTROL = 0x00020000,    WRITE_DAC = 0x00040000,    WRITE_OWNER = 0x00080000,    SYNCHRONIZE = 0x00100000,    STANDARD_RIGHTS_REQUIRED = 0x000F0000,    STANDARD_RIGHTS_READ = 0x00020000,    STANDARD_RIGHTS_WRITE = 0x00020000,    STANDARD_RIGHTS_EXECUTE = 0x00020000,    STANDARD_RIGHTS_ALL = 0x001F0000,    SPECIFIC_RIGHTS_ALL = 0x0000FFFF,    ACCESS_SYSTEM_SECURITY = 0x01000000,    MAXIMUM_ALLOWED = 0x02000000,    GENERIC_READ = 0x80000000,    GENERIC_WRITE = 0x40000000,    GENERIC_EXECUTE = 0x20000000,    GENERIC_ALL = 0x10000000,    DESKTOP_READOBJECTS = 0x00000001,    DESKTOP_CREATEWINDOW = 0x00000002,    DESKTOP_CREATEMENU = 0x00000004,    DESKTOP_HOOKCONTROL = 0x00000008,    DESKTOP_JOURNALRECORD = 0x00000010,    DESKTOP_JOURNALPLAYBACK = 0x00000020,    DESKTOP_ENUMERATE = 0x00000040,    DESKTOP_WRITEOBJECTS = 0x00000080,    DESKTOP_SWITCHDESKTOP = 0x00000100,    WINSTA_ENUMDESKTOPS = 0x00000001,    WINSTA_READATTRIBUTES = 0x00000002,    WINSTA_ACCESSCLIPBOARD = 0x00000004,    WINSTA_CREATEDESKTOP = 0x00000008,    WINSTA_WRITEATTRIBUTES = 0x00000010,    WINSTA_ACCESSGLOBALATOMS = 0x00000020,    WINSTA_EXITWINDOWS = 0x00000040,    WINSTA_ENUMERATE = 0x00000100,    WINSTA_READSCREEN = 0x00000200,    WINSTA_ALL_ACCESS = 0x0000037F}[DllImport("user32.dll", SetLastError = true)]public static extern nint OpenInputDesktop(uint dwFlags, bool fInherit, ACCESS_MASK dwDesiredAccess);[DllImport("user32.dll", SetLastError = true)]public static extern bool CloseDesktop(nint hDesktop);[DllImport("user32.dll", SetLastError = true)]public static extern bool SetThreadDesktop(nint hDesktop);[DllImport("user32.dll", SetLastError = true)]public static extern bool SwitchDesktop(nint hDesktop);private static nint lastInputDesktop;public static bool SwitchToInputDesktop(){    try    {        CloseDesktop(lastInputDesktop);        nint inputDesktop = OpenInputDesktop();        if (inputDesktop == nint.Zero)        {            return false;        }        bool result = SetThreadDesktop(inputDesktop);        result &= SwitchDesktop(inputDesktop);        lastInputDesktop = inputDesktop;        return result;    }    catch (Exception ex)    {        return false;    }}

2、截屏使用

在调用 TryAcquireNextFrame 获取一帧之前,调用 SwitchToInputDesktop

C#
SwitchToInputDesktop();SharpDX.DXGI.Resource desktopResource = null;OutputDuplicateFrameInformation frameInfo = new OutputDuplicateFrameInformation()Result result = mDeskDupl.TryAcquireNextFrame(30, out frameInfo, out desktopResource);

3、模拟键盘使用

模拟键盘比较特殊,定时检测

C#
public const int KEYEVENTF_EXTENDEDKEY = 0x0000;public const int KEYEVENTF_KEYUP = 0x0002;[DllImport("user32.dll")]public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);private readonly  ConcurrentQueue<Action> inputActions = new();private void CheckQueue(){    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();    Task.Factory.StartNew((a) =>    {        CancellationTokenSource tks = a as CancellationTokenSource;        while (tks.IsCancellationRequested == false)        {            if (inputActions.IsEmpty == false)            {                try                {                    if (inputActions.TryDequeue(out var action))                    {                        if (Win32Interop.SwitchToInputDesktop()==false)                        {                            tks.Cancel();                            CheckQueue();                        }                        action();                    }                }                finally                {                }            }            else            {                Thread.Sleep(10);            }        }    }, cancellationTokenSource, TaskCreationOptions.LongRunning);}private void TryOnInputDesktop(Action inputAction){    inputActions.Enqueue(() =>    {        try        {            inputAction();        }        catch (Exception)        {        }    });}

调用

C#
//先调用CheckQueue定时检测CheckQueue();//模拟键盘TryOnInputDesktop(() =>{    keybd_event(key, (byte)User32.MapVirtualKey(key, 0),type , 0);});


打赏

本文链接:https://www.kinber.cn/post/6397.html 转载需授权!

分享到:


推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

 您阅读本篇文章共花了: 

群贤毕至

访客