此次MFC的远程桌面共享端源代码地址:http://download.csdn.net/download/wochendaixin/10119977 点击打开链接
编译运行环境:win10, vs2017
调试时,注意让 共享端 和 连接端 在同一局域网中。
一、RDP远程桌面共享端
(1)准备好和RDP共享相关的调用
之前一直在纠结由c#转MFC之后,调用包装类产生的函数和MSDN有差别。在查了一片源代码后发现根本不需要去使用包装类。在我的 分享端 工程里通过直接引用一个特殊头文件即可调用那些和RDP远程共享相关的一些列成员和函数。这时,就可以对照MSDN来进行共享流程代码的编写了
#include"rdpencomapi.h"
//这个头文件就在C盘里面,具体位置可以网上查到,或者直接在C盘下查找
//找到这个头文件之后,引进你的工程
IRDPSRAPISharingSession* p_ShareSession;//这些类型都可以在MSDN查找。下面的步骤都是按照MSDN上的顺序来的
CMyRDPSessionEvents myEvents;
IRDPSRAPIInvitationManager* p_InvitationManager;
IRDPSRAPIInvitation* p_Invitation;
HRESULT hr=CoCreateInstance(__uuidof(RDPSession),NULL,CLSCTX_ALL, __uuidof(IRDPSRAPISharingSession),reinterpret_cast<void**>(&p_ShareSession));
if (FAILED(hr)) return;
//{========添加事件通知。比如有 新的接入、请求控制(这里会涉及一些情况的调用,在后面(3)再说)===========
IConnectionPointContainer* pConnectionPointContainer = NULL;
IConnectionPoint* pConnectionPoint = NULL;
unsigned long cid;//connection id, critical,use it to unadvise
hr = p_ShareSession->QueryInterface(IID_IConnectionPointContainer, reinterpret_cast<void**>(&pConnectionPointContainer));
if (FAILED(hr)) return;
if (pConnectionPointContainer)
{
pConnectionPointContainer->FindConnectionPoint(__uuidof(_IRDPSessionEvents), &pConnectionPoint);
if (pConnectionPoint) {
pConnectionPoint->Advise(&myEvents, &cid);
}
}
//==================================================================================================}
//开启共享
p_ShareSession->Open();
if (!p_ShareSession) return;
//生成邀请字符串
p_ShareSession->get_Invitations(&p_InvitationManager);
hr = p_InvitationManager->CreateInvitation(B("baseAuth"),B("groupName"), B(""), 10, &p_Invitation);
if (FAILED(hr))return;
BSTR bstr ;
p_Invitation->get_ConnectionString(&bstr);
//BSTR转char*,写入文本 或者 用socket发送
_bstr_t p = bstr;
char*lpszText2 = p;
ofstream out;
out.open("D:\\3.xml", ios::trunc);//根据自己需要进行适当的选取
if(out.is_open())
{
out<< lpszText2;
out.close();
}
(3)关于第二步骤中的一些事件通知
在我参考的那个例子中,无论是作为共享端还是作为连接端。都是需要对各种事件做出响应的。在我的工程中,只是简单处理了两个事件:
【1】当有连接者连入时,共享端要响应这个事件,并将新连入的这个连接者的级别设置为 “观看级”
【2】当连接者想要提升自己的权限时,共享端要响应这个事件,将这个连接者的级别更改为“控制级”。
当然这些响应的处理是放在单独的一个 .h和.cpp中声明定义的。即我的工程中的 MyRDPSessionEvents.h 和 MyRDPSessionEvents.cpp
在一开始我尝试过不做这些响应,也就是在(2)的步骤中舍去了虚线框画的那段代码。结果在运行时 连接端无法得到分享的画面和进行控制。我猜测可能是需要在共享端提前为连接者分配一定的权限吧。
二、连接端
连接端主要就用了一个Activex控件。
直接在MFC的对话框中,右键-》添加ActiveX控件 -》rdpviewer class.
然后,为这个新添加的控件,右键关联一个变量即可。这样就会得到一个类似:CRdpviewer1 Cm_viewer;之后的一些列操作都是用这个变量类中的方法
流程如下:
//1.从文件中读出那个共享端产生的邀请字符串
//自己定义的功能函数
string ConnectionString = readfile();//
wstring temp = s2ws(ConnectionString);
//2.连接
Cm_viewer.Connect(temp.c_str(), L"Viewer1",L"");
//3.申请提高自己的权限为“控制”
Cm_viewer.RequestControl(CRdpviewer1::CTRL_LEVEL_INTERACTIVE);