Writing a Desktop Sharing Application

Writing a Desktop Sharing Application

Rate This
 

Windows Desktop Sharing (WDS) API provides a rich set of API to share your complete desktop or just individual applications. Below is a step-by-step guide to write a sharing application. I have chosen C#/.Net to make things simpler and we will be using Visual Studio 2005 as the IDE.

Windows Desktop Sharing API Introduction:

Windows Desktop Sharing API allows a Windows Desktop Session to be shared across multiple viewers. More information on the API can be found on MSDN at http://msdn2.microsoft.com/en-us/library/aa373852.aspx. You could also refer to the Windows Desktop Sharing API Introduction blog. Windows Meeting Space & Remote Assistance use WDS API for collaboration and assistance scenarios. Similarly, you can write applications to achieve your sharing, collaboration, assistance, administration and deployment scenarios. 

Object Model of the API: API currently is published as an in-proc COM DLL (RdpEncom.dll) and is available in Vista. There are 2 primary objects that can be created:

  • 1. IRDPSRAPISharingSession - COM object that enables sharing of desktop
  • 2. IRDPSRAPIViewer - ActiveX control that can be embedded into a host window for viewing the sharing session.

Other objects can be created or queried from these 2 primary objects. There is also an event sink interface (IRDPSessionEvents) that the API would use to report events to the application. Applications should sink appropriate events as needed.

Desktop Sharing Application: Writing a desktop sharing application involves writing 2 different applications - one for sharing and the other for viewing.  These 2 applications can be written as one application working in different modes similar to Windows Meeting Space.

Sharer Application: You can choose to create either a console based application or windows based application. It is nice to have a GUI interface to control the viewers, start/stop sharing etc., so let's build a windows application. To create a sharer application you will need to first add a reference to RdpComApi 1.0 Type Library (rdpencom.dll in %windows%\system32 directory) to your project.

Starting the sharing Session: To start the sharer, first create an instance of RdpSession Class and then subscribe to the events published by the WDS API. For this you will need to declare an event handler of the corresponding delegate signature. Here is an example of declaring and defining an event handler:

private void OnAttendeeConnected(object pObjAttendee)

{

IRDPSRAPIAttendee pAttendee = pObjAttendee as IRDPSRAPIAttendee;

pAttendee.ControlLevel = CTRL_LEVEL.CTRL_LEVEL_VIEW;

LogTextBox.Text += ("Attendee Connected: " + pAttendee.RemoteName + Environment.NewLine);

}

 

Above is the event handler for the delegate:

void _IRDPSessionEvents_OnAttendeeConnectedEventHandler(object pAttendee);

 

This event is fired by the API when an attendee connects to the sharing session and will pass in the attendee instance to the event handler. Use that attendee instance to query information and also to set control level of the attendee. Control levels define the level of information that an attendee gets. In this implementation of event handler, attendee is given view control which means that attendee can only see the sharing session but cannot interact with it. We also print out some message to a text box so that the user who is running the sharing app can see the status of attendees connecting and disconnecting. Similarly we add event handlers for attendee disconnected and control level change requests.

After subscribing to the events that we are interested in, start the sharing session by calling Open() method on the RdpSession object. 

// Create a new RdpSession instance

m_pRdpSession = new RDPSession();

 

// Subscribe to events

m_pRdpSession.OnAttendeeConnected += new _IRDPSessionEvents_OnAttendeeConnectedEventHandler(OnAttendeeConnected);

m_pRdpSession.OnAttendeeDisconnected += new _IRDPSessionEvents_OnAttendeeDisconnectedEventHandler(OnAttendeeDisconnected);

m_pRdpSession.OnControlLevelChangeRequest += new _IRDPSessionEvents_OnControlLevelChangeRequestEventHandler(OnControlLevelChangeRequest);

 

// Start the Sharing Session

m_pRdpSession.Open();

LogTextBox.Text += "Presentation Started. Your Desktop is being shared." + Environment.NewLine;

 

Creating an Invitation: Create an invitation that can be sent to attendees so that they can use the invitation to connect to the sharing session. The invitation can be sent to the attendees using any mechanism desired. For example, Remote assistance allows to save the invitation and send it by email or to send through IM. Windows Meeting space uses "People Near Me" feature to identify and then send the invitations. In this implementation, let's take a simple approach and save it to a file. Here is the corresponding code:

// Create invitation.

IRDPSRAPIInvitation pInvitation = m_pRdpSession.Invitations.CreateInvitation("WinPresenter","PresentationGroup","",5);

string invitationString = pInvitation.ConnectionString;

// Save Connection String to File

WriteToFile(invitationString);

 

Stopping the Sharing Session: To stop the sharing session, call close method on the RdpSession class instance. Here is the code:

m_pRdpSession.Close();

LogTextBox.Text += "Presentation Stopped." + Environment.NewLine;

Marshal.ReleaseComObject(m_pRdpSession);

m_pRdpSession = null;

 

You may notice that I am calling ReleaseComObject. Reason being that once Close() is called then that RdpSession class instance cannot be used anymore. We will need to create another instance of RdpSession class to restart sharing.

Viewer Application: You will need to create a windows application and then add RdpViewer Class as an ActiveX control. Adding ActiveX controls to Windows Forms is a good resource to learn about adding ActiveX controls in Visual Studio IDE. Visual Studio will create an instance of AxRdpViewer and you can resize the ActiveX control to fit to your needs on the Windows Form. You can also choose to create this ActiveX control dynamically and place it in the host Form.

 

Connecting to the Sharing Session: First subscribe to the events that you are interested in. The easiest way in Visual Studio to add event handlers to an event is to click on the Events lightning bolt in the property browser of ActiveX control, then double-click on any events you wish to handle. An empty method signature and the appropriate event hooking and unhooking code are then emitted for you.  Subscribe to OnConnectionEstablished, OnConnectionTerminated, OnConnectionFailed and OnError events at a minimum so that you can report status and errors, if there are any. Here is some code for OnError event handler method:

private void OnError(object sender, _IRDPSessionEvents_OnErrorEvent e)

{

int ErrorCode = (int)e.errorInfo;

LogTextBox.Text += ("Error 0x" + ErrorCode.ToString("X") + Environment.NewLine);

}

To connect to the Sharing Session, you will need an invitation. Since we saved the invitation created in the Sharing Application as a file, let's just read the file into a string. Then call Connect method with the invitation file. Please note that we are passing empty string as password. Since we created the invitation on the sharing application with empty string as the password this would work. This is not advised if you are writing a commercial application because anyone can connect to your Sharing Session if they can get hold of the invitation.

Here is the code to connect to the Sharing Session:

string ConnectionString = ReadFromFile();

if (ConnectionString != null)

{

pRdpViewer.Connect(ConnectionString, "Viewer1", "");

}

Once the connection is succesfully established with sharing session, API will fire OnConnectionEstablished event or OnConnectionFailed event if the connection fails.

 

Disconnecting from the Sharing Session: To disconnect from the sharing session, call Disconnect method on the AxRdpViewer class instance. Here is the code:

pRdpViewer.Disconnect();

 

API will fire OnConnectionTerminated event once the viewer is disconnected from the sharing session.

Wrapping up:

This is all you need to do to share your desktop. Obviously you will need to do much more if you want to have control on who is connected, display a nice GUI for attendee information, kick attendees etc. This will give you a good start and explore the API provided by WDS API to achieve your other scenarios.

Sample Application:

WinPresenter is a sample Desktop Sharing Suite of applications encompassing both Sharing and Viewing application. You should be able to find source code including the snippets above. I left out error checking, printing messages to user etc., so please modify it to your needs.

Usage of Sample Applications:

Sharer Application: Run winsharer.exe. Invitation file will be saved to the current directory with file name inv.xml

Viewer application: Run winviewer.exe %path to invitation file%. Either specify the directory where you have run the winsharer or copy inv.xml to some other location and specify the path. If there is no path specified it will try to read inv.xml from the current directory.

Attachment: WinPresenterFinal.zip
Leave a Comment
  • Please add 6 and 3 and type the answer here:
  • Post
  • Hi Ann, there is no way to redirect drives from viewer to sharer.

  • Hi Dipak, Could you let me know the following details:

    1. OS that the sharer is running on.

    2. Color depth of the machine that the sharer is running on.

    3. Have you set any color depth through the API on the sharer?

    Thanks!

  • Hi Srneerud,

    Sorry for late reply.

    Ans-1: The sharer is running on Windows 7 (Autoupdates are ON).

    Ans-2: Color Dpeth of the sharer's machine is 32 bit

    Ans-3: No. I don't set any color depth through API on the sharer. In fact the sharer is same as in sample application.

    Note: The Sharer's desktop resolution is 1366 x 768 where as Viewer has resolution 1024x768.

    Another problem:

    I am trying to continue to share the desktop when user has locked the desktop. But the session get paused. Can you please help on this as well?

    Thanks.

  • The application not working in windows xp or i dont know how to run it please provide the step by step procedure in windows xp...

    Thanks in Advance.

  • Based on this concept we build a desktop sharing application to assist our support team. We are using reverse connecting to handle firewall problems, but we're experiencing some problems we can't explain. Maybe you have some ideas...

    For now our customer can start the server component which connects to a client component running at our support team. The desktop sharing session starts and our supporter has control of the mouse cursor and the applications on the customer's desktop. Great! But after a while (for example 5 minues)  the supporter looses the ability to control the mouse. He still sees the desktop content of the customer at a nice speed, but cannot interact. In our solution we're using virtual channels to send commands from the client to the server, but this still works, so the communication from the client to the server is still open. Do you know about similar problems or possible reasons for this behavior? If you need further information I will be pleases to supply them.

  • Reading the connection string from the file name inv.xml

    Error in Reading input file. Error Info: System.IO.FileNotFoundException

    i get this error when i press the conect button. inv.xml is missing. what can i do to avoid that. plz reply

  • Copy the inv.xml from the sharer\presenter machine to the viewer machine (into the same folder that the viewer app is running from). It is generated when you click "Open" on the presenter application in the same folder that the presenter app runs from.

  • This app works file on internet if one of the sharer or viewer having an public IP, but if both are behind NAT, communication is not happening at all.

    What is the reason and what can be the solution?

  • Hi, very nice article! It is a lot of fun to play with this api. I have written a sharer and a viewer application using Windows Forms. Both can connect and are running fine (Windows 7 64 bit). But I have one small problem: Normally the mouse pointer on the sharers side is synchronized with the viewer so that the viewer can interact with the sharers desktop. This is of course a wanted behaviour. But it also seems to synchronize the mouse pointer when the viewer is in interactive mode but the viewer window has NOT the focus. The result is that the mouse "jumps" on the sharers side to an unwanted position, making it almost impossible to work. This happens every 15 seconds and only, when the viewer is in "interactive" mode, not in "view" mode.

    What I want is an application where the viewer can always stay in "interactive" mode but the mouse pointer may not be synchronized to the sharer if the viewer window has not the focus. I want to avoid to implement a behaviour that the viewer switches to "view"  mode every time the view windows loses focus and switch back to "interactive" mode when it regains focus.

    Difficult to explain, I hope yout get the point, English is not my native language. Could someone help please?

    Cabra

  • Hello, I've a trouble with PortID and a reverse connection

    I try

       AxRDPViewer1.Properties("PortId") = 4000

    the I open the incoming socket

    AxRDPViewer1.StartReverseConnectListener

    The problem is the seems PortId is ignored: my connection string reports other ports number, and the incoming socket is open on port different from 4000..

    any idea?

    thanks

  • Hi,

    is it possible to run the example and Windows Desktop Sharing in general in the following constellation:

    - Windows 7 runs on the client computer

    - Windows 7 or Windows 7 embedded runs on the server computer

    Thanks for any answer,

    Rebekka

  • Hi,

    Firstly great post. Though I am also having the problem with the skew screen and garbled. Same

    as Dipak. Any help will be great.

    Thanks

    Louis

  • I have downloaded the code and run the application, but where should I give the remote server name pasword . also when I click connect it throws an error  

  • I have downloaded the code and run the application, but where should I give the remote server name pasword . also when I click connect it throws an error  

  • Hi to all,

    We have created Desktop Sharing Application using this Windows Desktop Sharing (WDS) API. It is working well in LAN Connection but we want to use it with Static IP Address. Suppose I am in USA and want to see screen of my Company’s PC/Machine at my office (In Canada) so how can I use Windows Desktop Sharing (WDS) API to connect PC/Machine using Static IP Address?

    Can you please help me to do this? Please send us your feedback.

    Thank You!

    Rasik Godhani

Page 7 of 10 (140 items) «56789»