zoukankan      html  css  js  c++  java
  • PCB 一键远程桌面+RDP文件生成

    最近在写个内网INCAM内网授权工具中,在服务端监听客户端请求后,后台自动处理客户端请求并远程客户端

    这里记录3个点。

    一.运行RDP文件后,正常会有下图2个弹窗,怎么可以关闭这2个弹窗呢,

    通过模拟按键ALT+N,ALT+Y

    二.客户端与服务端状态如何控制的,客户端发起请求:状态流程图

    三.实现部份代码:

     private bool DeskLink(string IPAddress, string Domain, string UserName, string Password)
            {
                bool isOK = false;
                DelMstsc();
                string address = IPAddress;
                string domain = Domain;
                string username = UserName;
                string password = Password;
                string filename = "incam专用.rdp";
                var TemplateStr = RDPdemo.Properties.Resources.TemplateRDP;//获取RDP模板字符串
                var pwstr = BitConverter.ToString(DataProtection.ProtectData(Encoding.Unicode.GetBytes(password), ""));
                pwstr = pwstr.Replace("-", "");
                var NewStr = TemplateStr.Replace("{#domain}", domain).Replace("{#address}", address).Replace("{#username}", username).Replace("{#password}", pwstr);
                StreamWriter sw = new StreamWriter(filename);
                sw.Write(NewStr);
                sw.Close();
                ProcCmd("mstsc " + filename);
                Thread.Sleep(1000);
                bool isWinExist2 = isWindowsExistSleep("远程桌面连接", "是(&Y)", 200);
                if (!isWinExist2)
                {
                    bool isWinExist1 = isWindowsExistSleep("远程桌面连接", "连接(&N)", 3000);
                    if (isWinExist1)
                    {
                        Thread.Sleep(20);
                        API.OpenIcon(hwnd);
                        API.SetForegroundWindow(hwnd);
                        Thread.Sleep(20);
                        SendKeys.SendWait("%n"); //Shift  +    Ctrl  ^  Alt  %
                        //API.keybd_event((int)Keys.Alt, API.MapVirtualKeyA((int)Keys.Alt, 0), 0, 0);
                        //API.keybd_event((int)Keys.N, API.MapVirtualKeyA((int)Keys.N, 0), 0, 0);
                        //API.keybd_event((int)Keys.N, API.MapVirtualKeyA((int)Keys.N, 0), 2, 0);
                        //API.keybd_event((int)Keys.Alt, API.MapVirtualKeyA((int)Keys.Alt, 0), 2, 0);
                        Thread.Sleep(1000);
                    }
                }
    
                isWinExist2 = isWindowsExistSleep("远程桌面连接", "是(&Y)", 5000);
                if (isWinExist2)
                {
                    Thread.Sleep(20);
                    API.OpenIcon(hwnd);
                    API.SetForegroundWindow(hwnd);
                    Thread.Sleep(20);
                    SendKeys.SendWait("%y"); //Shift  +    Ctrl  ^  Alt  %
                    //API.keybd_event((int)Keys.Alt, API.MapVirtualKeyA((int)Keys.Alt, 0), 0, 0);
                    //API.keybd_event((int)Keys.Y, API.MapVirtualKeyA((int)Keys.Y, 0), 0, 0);
                    //API.keybd_event((int)Keys.Y, API.MapVirtualKeyA((int)Keys.Y, 0), 2, 0);
                    //API.keybd_event((int)Keys.Alt, API.MapVirtualKeyA((int)Keys.Alt, 0), 2, 0);
                    Thread.Sleep(20);
                }
                bool isWinDesk = isWindowsExistSleep($"incam专用 - {address} - 远程桌面连接", "", 10000);
                isOK = isWinDesk;
                if (isWinDesk)
                API.ShowWindow(hwnd, 2);
                return isOK;
            }
            public IntPtr hwnd = IntPtr.Zero;
            public IntPtr hwndChild = IntPtr.Zero;
            public bool isWindowsExistSleep(string WindowName, string ChildWindowName, int SleepCountTime)
            {
                int SleepTime = SleepCountTime / 100;
                int i = 0;
                bool isWinExist = isWindowsExist(WindowName, ChildWindowName);
                while (i < SleepTime && !isWinExist)
                {
                    Thread.Sleep(100);
                    isWinExist = isWindowsExist(WindowName, ChildWindowName);
                    i++;
                }
                return isWinExist;
            }
            /// <summary>
            /// 主窗体和子存体名同时存在 则为true
            /// </summary>
            /// <param name="WindowName"></param>
            /// <param name="ChildWindowName"></param>
            /// <returns></returns>
            public bool isWindowsExist(string WindowName, string ChildWindowName)
            {
                hwnd = API.FindWindowAPI(null, WindowName);
                if (hwnd == IntPtr.Zero)
                    return false;
                if (!string.IsNullOrEmpty(ChildWindowName))
                {
                    hwndChild = API.FindWindowEx(hwnd, IntPtr.Zero, null, ChildWindowName);
                    if (hwndChild == IntPtr.Zero)
                        return false;
                }
                return true;
            }
    [Serializable()]
        public sealed class DataProtection
        {
            [Flags()]
            public enum CryptProtectPromptFlags
            {
                CRYPTPROTECT_PROMPT_ON_UNPROTECT = 0x01,
                CRYPTPROTECT_PROMPT_ON_PROTECT = 0x02,
                CRYPTPROTECT_PROMPT_RESERVED = 0x04,
                CRYPTPROTECT_PROMPT_STRONG = 0x08,
                CRYPTPROTECT_PROMPT_REQUIRE_STRONG = 0x10
            }
    
            [Flags()]
            public enum CryptProtectDataFlags
            {
                CRYPTPROTECT_UI_FORBIDDEN = 0x01,
                CRYPTPROTECT_LOCAL_MACHINE = 0x04,
                CRYPTPROTECT_CRED_SYNC = 0x08,
                CRYPTPROTECT_AUDIT = 0x10,
                CRYPTPROTECT_NO_RECOVERY = 0x20,
                CRYPTPROTECT_VERIFY_PROTECTION = 0x40,
                CRYPTPROTECT_CRED_REGENERATE = 0x80
            }
    
            #region 加密数据
            public static string ProtectData(string data, string name)
            {
                return ProtectData(data, name,
                    CryptProtectDataFlags.CRYPTPROTECT_UI_FORBIDDEN | CryptProtectDataFlags.CRYPTPROTECT_LOCAL_MACHINE);
            }
    
            public static byte[] ProtectData(byte[] data, string name)
            {
                return ProtectData(data, name,
                    CryptProtectDataFlags.CRYPTPROTECT_UI_FORBIDDEN | CryptProtectDataFlags.CRYPTPROTECT_LOCAL_MACHINE);
            }
    
            public static string ProtectData(string data, string name, CryptProtectDataFlags flags)
            {
                byte[] dataIn = Encoding.Unicode.GetBytes(data);
                byte[] dataOut = ProtectData(dataIn, name, flags);
    
                if (dataOut != null)
                    return (Convert.ToBase64String(dataOut));
                else
                    return null;
            }
    
            /// <summary>
            /// 加密数据
            /// </summary>
            /// <param name="data">要加密的明文数据</param>
            /// <param name="name">有意义的描述,此描述会加到加密后的数据中</param>
            /// <param name="dwFlags">flags的位标志</param>
            /// <returns></returns>
            private static byte[] ProtectData(byte[] data, string name, CryptProtectDataFlags dwFlags)
            {
                byte[] cipherText = null;
    
                // copy data into unmanaged memory
                //DATA_BLOB结构,用于CryptProtectData参数
                DPAPI.DATA_BLOB din = new DPAPI.DATA_BLOB();
                din.cbData = data.Length;
    
                //Marshal类的作用:提供了一个方法集,这些方法用于分配非托管内存、复制非托管内存块、将托管类型转换为非托管类型,
                //此外还提供了在与非托管代码交互时使用的其他杂项方法。 
                //为din.pbData分配内存
                din.pbData = Marshal.AllocHGlobal(din.cbData);
    
                //InPtr结构:用于表示指针或句柄的平台特定类型
                //分配内存错误,抛出内存不足异常
                //IntPtr.Zero:一个只读字段,代表已初始化为零的指针或句柄
                if (din.pbData.Equals(IntPtr.Zero))
                    throw new OutOfMemoryException("Unable to allocate memory for buffer.");
    
                //将data数组中的数据复制到pbData内存指针中
                Marshal.Copy(data, 0, din.pbData, din.cbData);
    
                //声明DPAPI类的DATA_BLOB公共结构类型
                DPAPI.DATA_BLOB dout = new DPAPI.DATA_BLOB();
    
                try
                {
                    //加密数据
                    bool cryptoRetval = DPAPI.CryptProtectData(ref din, name, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, dwFlags, ref dout);
    
                    //判断加密是否成功
                    if (cryptoRetval) // 成功
                    {
                        int startIndex = 0;
                        //分配cipherText数据元素大小为dout.cbData
                        cipherText = new byte[dout.cbData];
                        //从dout.pbData内存指针指向的内容拷贝到byte数组cipherText中
                        Marshal.Copy(dout.pbData, cipherText, startIndex, dout.cbData);
                        //从内存中释放指针指向的数据I
                        DPAPI.LocalFree(dout.pbData);
                    }
                    else
                    {
                        //加密失败,获得错误信息
                        int errCode = Marshal.GetLastWin32Error();
                        StringBuilder buffer = new StringBuilder(256);
                        //显示错误信息
                        Win32Error.FormatMessage(Win32Error.FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, errCode, 0, buffer, buffer.Capacity, IntPtr.Zero);
                    }
                }
                finally
                {
                    // 如果din.pbData非空,则释放din.pbData使用的内存
                    if (!din.pbData.Equals(IntPtr.Zero))
                        Marshal.FreeHGlobal(din.pbData);
                }
    
                //返回加密后的数据
                return cipherText;
            }
            #endregion
    
    
            //解密数据
    
            internal static void InitPromptstruct(ref DPAPI.CRYPTPROTECT_PROMPTSTRUCT ps)
            {
                ps.cbSize = Marshal.SizeOf(typeof(DPAPI.CRYPTPROTECT_PROMPTSTRUCT));
                ps.dwPromptFlags = 0;
                ps.hwndApp = IntPtr.Zero;
                ps.szPrompt = null;
            }
        }
    
        //允许托管代码不经过堆栈步即调入非托管代码
        [SuppressUnmanagedCodeSecurityAttribute()]
        internal class DPAPI
        {
            [DllImport("crypt32")]
            public static extern bool CryptProtectData(ref DATA_BLOB dataIn, string szDataDescr, IntPtr optionalEntropy, IntPtr pvReserved,
                IntPtr pPromptStruct, DataProtection.CryptProtectDataFlags dwFlags, ref DATA_BLOB pDataOut);
    
            [DllImport("crypt32")]
            public static extern bool CryptUnprotectData(ref DATA_BLOB dataIn, StringBuilder ppszDataDescr, IntPtr optionalEntropy,
                IntPtr pvReserved, IntPtr pPromptStruct, DataProtection.CryptProtectDataFlags dwFlags, ref DATA_BLOB pDataOut);
    
            [DllImport("Kernel32.dll")]
            public static extern IntPtr LocalFree(IntPtr hMem);
    
            [StructLayout(LayoutKind.Sequential)]
            public struct DATA_BLOB
            {
                public int cbData;
                public IntPtr pbData;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct CRYPTPROTECT_PROMPTSTRUCT
            {
                public int cbSize; // = Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT))
                public int dwPromptFlags; // = 0
                public IntPtr hwndApp; // = IntPtr.Zero
                public string szPrompt; // = null
            }
        }
    
    
        internal class Win32Error
        {
            [Flags()]
            public enum FormatMessageFlags : int
            {
                FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x0100,
                FORMAT_MESSAGE_IGNORE_INSERTS = 0x0200,
                FORMAT_MESSAGE_FROM_STRING = 0x0400,
                FORMAT_MESSAGE_FROM_HMODULE = 0x0800,
                FORMAT_MESSAGE_FROM_SYSTEM = 0x1000,
                FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x2000,
                FORMAT_MESSAGE_MAX_WIDTH_MASK = 0xFF,
            }
    
            [DllImport("Kernel32.dll")]
            public static extern int FormatMessage(FormatMessageFlags flags, IntPtr source, int messageId, int languageId,
                StringBuilder buffer, int size, IntPtr arguments);
        }
  • 相关阅读:
    Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    用户画像——“打标签”
    python replace函数替换无效问题
    python向mysql插入数据一直报TypeError: must be real number,not str
    《亿级用户下的新浪微博平台架构》读后感
    【2-10】标准 2 维表问题
    【2-8】集合划分问题(给定要分成几个集合)
    【2-7】集合划分问题
    【2-6】排列的字典序问题
    【2-5】有重复元素的排列问题
  • 原文地址:https://www.cnblogs.com/pcbren/p/9495313.html
Copyright © 2011-2022 走看看