Не удается отправить из Просмотрщика на хост с использованием виртуальных каналов с помощью общего рабочего стола Windows / RDPCOMAPILib - PullRequest
0 голосов
/ 04 декабря 2011

Я создаю приложение для общего доступа к рабочему столу Windows и у меня все работает, кроме виртуальных каналов для отправки сообщений чата.Я могу отправлять сообщения с хоста в Viewer, но не наоборот.Средство просмотра использует ActiveX RDPViewer.Проблема в том, что я не могу получить событие OnChannelDataRectained для запуска на хосте.Я знаю, что у некоторых людей были проблемы с этим раньше, но любая помощь будет признательна.

Вот некоторые фрагменты, которые могут помочь.Просмотрщик

RDPCOMAPILib.IRDPSRAPIVirtualChannel chan;
chan = rdpViewer.VirtualChannelManager.CreateVirtualChannel(name, RDPCOMAPILib.CHANNEL_PRIORITY.CHANNEL_PRIORITY_HI, 0);

Затем при отправке я звоню

chan.SendData(message, (int)RDPCOMAPILib.RDPENCOMAPI_CONSTANTS.CONST_ATTENDEE_ID_HOST, 0);

Хост

chan = rdp.VirtualChannelManager.CreateVirtualChannel(name, RDPCOMAPILib.CHANNEL_PRIORITY.CHANNEL_PRIORITY_HI, 0);
foreach(IRDPSRAPIAttendee attendee in rdp.Attendees)
            this.vc.SetAccess(attendee.Id, RDPCOMAPILib.CHANNEL_ACCESS_ENUM.CHANNEL_ACCESS_ENUM_SENDRECEIVE);

Затем я вызываю это для отправки данных

chan.SendData(message, (int)RDPCOMAPILib.RDPENCOMAPI_CONSTANTS.CONST_ATTENDEE_ID_EVERYONE, 0);

Ответы [ 2 ]

2 голосов
/ 14 марта 2012

Вот техника, которую я использую, которая хорошо подходит для моих нужд:

//----------------------------------------------------------------------------------------
// On the server/host, create a new session
//----------------------------------------------------------------------------------------
RDPSession session = new RDPSession();

// Then create a virtual channel
IRDPSRAPIVirtualChannel virtualChannel1 = session.VirtualChannelManager.CreateVirtualChannel("foo", CHANNEL_PRIORITY.CHANNEL_PRIORITY_HI, (uint)CHANNEL_FLAGS.CHANNEL_FLAGS_LEGACY);

// Now open the session
session.Open()

// And connect to the received event
session.OnChannelDataReceived += new _IRDPSessionEvents_OnChannelDataReceivedEventHandler(OnChannelDataReceived);

private void OnChannelDataReceived(object pChannel, int lAttendeeId, string bstrData) {
    Debug.WriteLine("Server::OnChannelDataReceived" + bstrData.Trim());
}

//----------------------------------------------------------------------------------------
// On the Client/Viewer side.
//----------------------------------------------------------------------------------------

// AxRDPViewer is the RDPViewer control on your form. Connect using the appropriate criteria.
AxRDPViewer.Connect(strInvitation, strName, strPassword);

// "Bind" the virtual channel by creating one using the same name as the one created on
// the server side.
IRDPSRAPIVirtualChannel virtualChannel1 = RDPViewer.VirtualChannelManager.CreateVirtualChannel("foo", CHANNEL_PRIORITY.CHANNEL_PRIORITY_HI, (uint)CHANNEL_FLAGS.CHANNEL_FLAGS_LEGACY);

// Hook the data received event
RDPViewer.OnChannelDataReceived += new AxRDPCOMAPILib._IRDPSessionEvents_OnChannelDataReceivedEventHandler(RDPViewer_OnChannelDataReceived);

private void RDPViewer_OnChannelDataReceived(object sender, AxRDPCOMAPILib._IRDPSessionEvents_OnChannelDataReceivedEvent e) {
    Debug.WriteLine("Client::OnChannelDataReceived:" + e.bstrData.Trim());
}

//----------------------------------------------------------------------------------------
// Sending data
//----------------------------------------------------------------------------------------

// Now, on both the server and client side, you can send data like this:

virtualChannel1.SendData("yippie!", (int)RDPENCOMAPI_CONSTANTS.CONST_ATTENDEE_ID_EVERYONE, (uint)CHANNEL_FLAGS.CHANNEL_FLAGS_LEGACY);

Надеюсь, это поможет. Я на самом деле боролся с этим некоторое время, но в итоге понял, что запускаю модальное диалоговое окно над формой, которое отвечает за перехват событий сеанса. Так что не делай этого. ;)

1 голос
/ 18 сентября 2018

Использование RDPENCOMAPI_CONSTANTS.CONST_ATTENDEE_ID_EVERYONE не работает для меня. Единственный способ решить эту проблему - использовать SendData итерацию по участникам сессии.

foreach (IRDPSRAPIAttendee a in _ctx.activeSession.Attendees)
    virtualChannel.SendData(msg, a.Id, Convert.ToUInt32(CHANNEL_FLAGS.CHANNEL_FLAGS_LEGACY));

Хотя это решает связь между хостом и программой просмотра, я все еще не могу получить сообщение от подключенного средства просмотра, зарегистрированного в том же виртуальном канале и использующего RDPENCOMAPI_CONSTANTS.CONST_ATTENDEE_ID_HOST константу.

На стороне сервера я создал новую RDPSession и виртуальный канал

activeSession = new RDPSession();
virtualChannel = activeSession.VirtualChannelManager.CreateVirtualChannel("myproto", CHANNEL_PRIORITY.CHANNEL_PRIORITY_HI, (uint)CHANNEL_FLAGS.CHANNEL_FLAGS_LEGACY);

создайте новый обработчик для события OnChannelDataReceived и запустите сеанс RDP.

activeSession.OnChannelDataReceived += new _IRDPSessionEvents_OnChannelDataReceivedEventHandler(OnChannelDataReceived);
activeSession.Open();

Обработчик событий выглядит так:

    private void OnChannelDataReceived(object pChannel, int lAttendeeId, string bstrData) {
       switch(bstrData) 
       {
            /* Handle commands here */
            case "mycmd":
                /* Process command and reply using SendData */
                break;

       }
    }

Средство просмотра работает в Windows 10, в то время как сервер работает в Windows 7, и оба они используют RDPCOMAPI, сгенерированный из Windows 7 rdpcomen.dll с использованием инструмента tlbimp.exe.

...