由于在学校需要管理很多主机的需要,自己动手写了个3389桌面集群的软件。
软件很简单,分别用2种方式实现:
(1)快速登入模式: 微软的MsRdpClient ActiveX控件实现
(2)远程桌面模式:生成.rdp文件实现
看似很简单的过程,在实现的过程中也不是一帆风顺。不管再简单的东西,我们也要力争把它做的最好!
首先,我们分析一下需要的功能:
(1)读写主机信息的功能模块(这里我用最简单的ini)
(2)主机信息的加密解密(涉及密码之类的需要加密处理保存)
(3)主机状态在线离线检查
(4)生成rdp文件并实现登陆
(5)配置文件导入导出
接着我来分享下遇到的问题
(1)使用MSTSCAX控件,断网导致使用控件的窗体卡死
MSTSCAX控件在一定程度上方便了我们在项目中处理远程桌面,如果不细读文档则会漏掉很多微软已经为我们封装好的功能。针对控件远程过程中断网导致的窗体卡死,我们只需要关闭rdp高级设置中的自动重连功能:m_MsRdpClientAdvancedSettings.put_EnableAutoReconnect(FALSE);
其他的很多远程桌面的属性都可以在CMsRdpClientAdvancedSettings6 ,CMsRdpClientSecuredSettings2中找到。
(2)服务器信息等内容,应该如何去存储和维护
读取配置文件,将配置文件保存在 std::map<SERVER, INFO> m_mapServerInfo 结构中,每一个SEVER对应唯一INFO,这里注意对<的重写(结构体作为map的key默认无法排序)
下面是我的SERVER和INFO结构:
代码语言:javascript复制typedef struct _SERVER_
{
CString name;
CString ip;
CString port;
CString user;
//map中key为结构体时需要重写<
bool operator <(const _SERVER_& other) const
{
if (ip < other.ip)
{
return true;
}
else if (ip == other.ip)
{
if (port < other.port)
{
return true;
}
else if (port == other.port)
{
if (user < other.user)
{
return true;
}
else if (user == other.user)
{
return false;
}
}
}
return false;
}
}SERVER, *PSERVER;
typedef struct _INFO_
{
CString password;
CString note;
}INFO, *PINFO;
将服务器信息保存在 m_mapServerInfo中我们只需要直接对m_mapServerInfo增改删的操作,最后再写入配置文件就可以。写配置文件线程我们可以设定一个全局变量g_hWriteThread保证对配置文件的写入:
代码语言:javascript复制 if (g_hWriteThread != INVALID_HANDLE_VALUE)
{
if (WaitForSingleObject(g_hWriteThread, 200) == WAIT_TIMEOUT)
{
::TerminateThread(g_hWriteThread, 0);
g_hWriteThread = INVALID_HANDLE_VALUE;
}
}
CWinThread * thread = AfxBeginThread((AFX_THREADPROC)WriteThread, this);
if (thread != NULL)
{
g_hWriteThread = thread->m_hThread;
}
(3)程序写完,无法运行于windows 7
我的开发环境是8.1 VS2013,开发完成以后release版本放置于windows7的电脑无法正常运行,有MSTSCAX的窗体根本无法加载,在window7上跟踪dlg.DoModal()到occcont.cpp第925行 IsWindow(pTemp->m_hWnd) 引发了一个断言终止,往前分析看,原来是MSTSCAX并没有加载起,进入资源视图,真相大白:
于是我在WIN7上删除MSTSCAX并重新加入,搞定,Release版本在WIN7,WIN8.1完美运行。
(4)在win7生成的RDP文件无法正常运行
按照网上提供的rdp文件的格式,并运用API:CryptProtectData获得远程加密密码,导出rdp文件,在win8完美运行,在win7上并非正常运行,执行mstsc.exe以后未完成自动登陆,并未从已生成的rdp文件读取任何信息,如图:
我很好奇为什么在win8可以win7却不行,在用winhex查看rdp之后我发现我在rdp文件开头漏掉了FFEF,说明RDP是以Unicode编码存储的,这也说明,win8读取存储文件默认以Unicode编码来读取,win7在未找到FFEF时,不会以Unicode读取。编码,测试成功!
总结:任何看似简单的问题都有值得学习和探索的地方,我不反对重复造轮子,但是一定要在造轮子过程中有自己的见解和收获,遇到问题格物致知,方能求得编程本质。
这个远程桌面集成软件大体写到这,如果你做相应功能遇到问题也可以回复交流讨论。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/181573.html原文链接:https://javaforall.cn