
Giving your users the ability to launch Remote Desktop from a Web link via RDP file is useful in a number of different scenarios. This is especially the case on a corporate Intranet where you want to maximize usability for employees and minimize the number of clicks.
(Just as an aside, note that for a variety of reasons (no framing, difficult to brand, awkward sign-in process, etc.) I do not consider the official Microsoft RDWeb site a viable option. As long as .rdp files are a viable option, I prefer to have these initiate remote desktop sessions from a Web page.
The Old Solution is no Longer Viable
In the past it was possible to directly point to .rdp files on a network share like this:
<a href="file:\\NetworkPath\SomeSharedFolder\MyRdpFile.rdp" target="_self">Click to start</a>
Both Internet Explorer 11 and Microsoft Edge would see this and happily start up a new remote desktop session. However now those times are over. IE11 is quickly fading away with no replacement planned. The original MS Edge is being replace with Chromium-based MS Edge. Both Chrome and Chromium-based MS Edge (and FireFox) sandbox users and do not allow linking to documents from a network share.
Basically the challenge is that the only remaining browser that supports pointing to a file on a network path is on borrowed time, so we need to find an alternate solution that works regardless of the browser.
This Calls for a New Solution
Rather than throwing in the towel and saying it is no longer possible to start start up remote desktop sessions from Web links, we’ll need to rethink what happens when a user clicks a link in their browser. Instead of asking the Web browser to download the RDP file from a network share and hoping it will do it, we’ll stream the file using some simple ASP.NET code (I’m giving the example using ASP.NET, but you can use any server side language that you prefer).
The plus side to this method is that it bypasses the browser sandbox rule. Streaming the file from code behind will work regardless of the browser that the user is using. So this is actually a significant upgrade!
Details of How to do it:
For starters, you’ll need to update your links so they run .NET code rather than being simple HTML hyperlinks. For simplicity I changed my links to run as LinkButton controls in a simple .NET WebForm.
Then I opened my RDP file and grabbed the existing settings that I know worked. I used a simple text editor to prefix and postfix the RDP settings so they are now encapsulated as a .NET string.
Once you’ve got the RDP in a String, you can then stream the file to the user who clicked on the Web link (as application/rdp). Also remember to set the name to something descriptive (instead of filename=TestRDP.rdp).
The Code (VB .NET)
Public Sub streamFile()
Dim strRDPFile As String = ""
strRDPFile &= " redirectclipboard:i:1" & ControlChars.CrLf
strRDPFile &= " redirectposdevices:i:0" & ControlChars.CrLf
strRDPFile &= " redirectprinters:i:1" & ControlChars.CrLf
strRDPFile &= " redirectcomports:i:1" & ControlChars.CrLf
strRDPFile &= " full address:s:ServerNameToConnectTo.Network.abc" & ControlChars.CrLf
strRDPFile &= " " & ControlChars.CrLf
Response.Buffer = True
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = "application/rdp"
Response.AddHeader("content-disposition", "attachment;filename=TestRDP.rdp")
Response.Write(strRDPFile)
Response.Flush()
Response.End()
End Sub
The Code (C#)
public void streamFile()
{
string strRDPFile = "";
strRDPFile += " redirectclipboard:i:1" + ControlChars.CrLf;
strRDPFile += " redirectposdevices:i:0" + ControlChars.CrLf;
strRDPFile += " redirectprinters:i:1" + ControlChars.CrLf;
strRDPFile += " redirectcomports:i:1" + ControlChars.CrLf;
strRDPFile += " full address:s:ServerName.Network.abc" + ControlChars.CrLf;
strRDPFile += " " + ControlChars.CrLf;
Response.Buffer = true;
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/rdp";
Response.AddHeader("content-disposition", "attachment;filename=TestRDP.rdp");
Response.Write(strRDPFile);
Response.Flush();
Response.End();
}