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();
bool isWinExist2 = isWindowsExistSleep("远程桌面连接", "是(&Y)", );
if (!isWinExist2)
{
bool isWinExist1 = isWindowsExistSleep("远程桌面连接", "连接(&N)", );
if (isWinExist1)
{
Thread.Sleep();
API.OpenIcon(hwnd);
API.SetForegroundWindow(hwnd);
Thread.Sleep();
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();
}
} isWinExist2 = isWindowsExistSleep("远程桌面连接", "是(&Y)", );
if (isWinExist2)
{
Thread.Sleep();
API.OpenIcon(hwnd);
API.SetForegroundWindow(hwnd);
Thread.Sleep();
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();
}
bool isWinDesk = isWindowsExistSleep($"incam专用 - {address} - 远程桌面连接", "", );
isOK = isWinDesk;
if (isWinDesk)
API.ShowWindow(hwnd, );
return isOK;
}
public IntPtr hwnd = IntPtr.Zero;
public IntPtr hwndChild = IntPtr.Zero;
public bool isWindowsExistSleep(string WindowName, string ChildWindowName, int SleepCountTime)
{
int SleepTime = SleepCountTime / ;
int i = ;
bool isWinExist = isWindowsExist(WindowName, ChildWindowName);
while (i < SleepTime && !isWinExist)
{
Thread.Sleep();
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, , 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 = ;
//分配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();
//显示错误信息
Win32Error.FormatMessage(Win32Error.FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, errCode, , 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 = ;
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);
}
PCB 一键远程桌面+RDP文件生成的更多相关文章
- PCB Windows远程桌面一键登录
开发时会经常需远程操作服务器,每次运行再也熟悉不过的命令 mstsc 或 mstsc -v 120.79.36.65 远程到目标服务器, 每次需输入密码,弹出烦人的 如何免密码一键登录呢,其实微软已 ...
- mac连接windows远程桌面及文件复制
最近更换mac办公,但由于之前是用windows,所以很多文件项目之类的东西都还在windows电脑中,一次都传到mac上又会比较占内存,并且使用率也不高,感觉不划算.但每次想用的时候,在从windo ...
- PowerShell自定义修改远程桌面RDP端口
应朋友的要求写了一个通过PowerShell修改远程桌面(Remote Desktop)端口的脚本,不复杂,启动脚本后有两个选项:1.自定义远程桌面:2.回复远程桌面的默认端口3389 发出来给有用的 ...
- windows修改远程桌面RDP连接数
windows 2003在默认情况下最多只允许两个用户进行远程终端连接,当达到两个远程桌面连接的到时候,再有人尝试连接,就会提示已经达到最大终端数,无法连上了. 一.windows2003终端连接数修 ...
- 关于KeePass实现mstsc远程桌面(rdp协议)的自动登录
本文的Keepass版本:KeePass Password Safe Version 2.45 首先介绍一下Keepass,引用官网的解释如下: KeePass is a free open sour ...
- 远程桌面RDP不能粘贴文本
刚才用远程桌面 登陆 服务器,突然发现不能在本机和远程服务器之间粘贴文本了,即不能从本机复制文本粘贴到服务器,也不能从服务器复制文本粘贴到本机. 在服务器上打开任务管理器,查看进程,有 rdpclip ...
- com组件远程桌面rdp模块的调用
rdp(remote desktop protocol)是一个多通道的协议,包括客户端视音传输.文件传输和通讯端口转向等等功能,通过压缩处理的数据网络传输也是相当快.我们在windows操作系统下面, ...
- 利用mstsc远程桌面传送文件,记录一下
尼玛之前服务器上传有点异常,在服务器装了一个上传下载监控的软件,用的是什么 绿色版QQ流量监控,绿色是挺绿色的,装了就等哭吧.没时间打字反正就是删除不了,后来想办法删除了.艹.所有服务除了系统服务能上 ...
- 禁止Windows远程桌面拷贝文件
通过组策略,我们可以解决以上问题,开始菜单运行输入gpedit.msc,进入“计算机配置”项,按顺序进入“管理模板”.“windows组件”.“终端服务”.“客户端/服务器数据重定向”.在详细描述栏中 ...
随机推荐
- more
参数选项: -num 指定屏幕显示大小为num行. +num 从行号num开始显示. -s 把连续多个空行显示为一行. -p 不滚屏,而是清除整个屏幕,然后显示文本. -c 不滚屏,而是从每一屏的顶部 ...
- java主要集合类的数据结构
1).ArrayList ArrayList维护着一个对象数组.如果调用new ArrayList()后,它会默认初始一个size=10的数组. 每次add操作都要检查数组容量,如果不够,重新 ...
- 大神所写的深度好文---Gradle 构建工具
什么是构建工具? 我们大家都知道 Gradle 是一种构建工具,那么什么是构建工具呢? 网上一大堆的文字解释我觉得很难理解,这里我以咱们 Android 开发来举个例子吧. 我们以前开发都是用 Ecl ...
- plsql developer连接oracle数据库
1.下载安装PLSQL Developer12 访问PLSQL Developer官网https://www.allroundautomations.com/bodyplsqldevreg.html, ...
- DECLARE_DYNAMIC
DECLARE_DYNAMIC(class_name) DECLARE_DYNCREATE 包含了DECLARE_DYNAMIC的功能,并且可以在运行过程中动态创建对象.如果需要动态创建类对象,需要使 ...
- Java字符字符串类
Java字符字符串类 Character 类 Character 类用于对单个字符进行操作.Character 类在对象中包装一个基本类型 char 的值在实际开发过程中,我们经常会遇到需要使用对象, ...
- 模态框(layer)
推荐一个好看的模态框(layer) 地址:http://layer.layui.com/ 相应列子及配置 全部来自于官网,可直接访问官网学习了解. //信息框-例1 layer.alert('见 ...
- vue移动端地址三级联动组件(二)
继续上一篇: 子组件css: <style scoped lang="less"> #city { width: 100%; height: 100%; positio ...
- My97DatePicker 开始日期不能大于 结束日期
My97DatePicker 日期控制,开始时间不能>结束时间,结束时间不能<开始时间 <li>日期:<input type="text" style ...
- enote笔记语言(4)(ver0.2)——“5w1h2k”分析法
章节:“5w1h2k”分析法 what:我想知道某个“关键词(keyword)”(即,词汇.词语,或称单词,可以是概念|专业术语|.......)的定义. why:我想知道事物发生的原因.“why ...