Articles‎ > ‎

Advanced RDC Configuration

Written by Greg Neagle   
Friday, 18 May 2007

In many enterprises, Mac users need occasional access to Windows applications. One common way to provide this access is to implement a Microsoft Terminal Server to host the applications. Mac users then connect to the Terminal Server using Microsoft's Remote Desktop Connection (RDC) client.

Remote Desktop Connection, a PowerPC-only application, generally works well, even on Intel Macs. It was a few shortcomings, most notably, the inability to host multiple simultaneous connections. But with some advanced configuration, this limitation can be eliminated and the user experience can be greatly improved.

Our goal is to provide users with an easy-to-understand method to simultaneously connect to multiple Windows applications hosted on a Windows Terminal Server.

Microsoft provides the Remote Desktop Connection application as a free download here.

Often, to help users connect to applications on Microsoft Terminal Servers, administrators will create RDC "connection documents". These are files that when double-clicked, launch the RDC client and cause it to connect to a certain terminal server, log in, and open a specific application. This method works well as long as the user only needs to connect to a single Terminal Session at a time. If you are providing a full Windows desktop via Terminal Services, and all the needed applications are on a single Terminal Server, a single session might be all your users will need. If, however, you provide access only to specific Windows applications (so that the application itself takes up the entire RDC window), or you need access to multiple Terminal Servers, the single-session limitation can become a problem.

Though the current RDC client cannot open multiple simultaneous connections, you can open multiple instances of RDC, each with its own Terminal Server session. You simply duplicate the RDC application. You can have as many open connections as you have copies of the RDC application. This, then, allows you to have multiple simultaneous open Terminal Server sessions. But the user experience can be poor - you'd have multiple RDC icons in the Dock, with no easy way to tell which one belongs to which session. Worse, there's no easy way to tell a RDC connection document to use a specific instance of the RDC application - which doesn't really allow the user to reliably double-click an icon to connect to a Windows application.

To solve these issues, we use an OS X feature: application bundles. Applications bundles are special folders that collect together resources needed by an application - icons, executables, configuration information, and more. These are bundled together in a directory that looks like an application icon - a user needs only to double-click it to launch the app. We can use this feature to bundle up the things we need to connect to a Terminal Server and to open a session.

Anatomy of a bundle
Let's look at the structure of an OS X application bundle:

Project.app/
    Contents/
        Info.plist
        MacOS/
            Project
        Resources/
            Icon.icns
            Project

In the example above, the application is called "Project".  Its top directory is named "Project.app".   "Sample.app" contains a single directory - "Contents".  "Contents" has three items: the "Info.plist" file, and the directories "MacOS" and "Resources".

The "Info.plist" file contains configuration information for the application bundle. For detailed info on these property lists, see Apple documentation - for example, http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigFiles.html

For our purposes, the only info we need to configure is the icon:

<plist>
<dict>
   <key>CFBundleIconFile</key>
   <string>Icon</string>
</dict>
</plist>

This simply declares that the name of our icon file is "Icon.ics" (you leave off the extension).  The file must be located in the Resources directory.

We'll skip the MacOS directory for a minute.  In the Resources directory, we put the Icon.ics file.  I used "Icon Composer, which is included with the Xcode Tools, to create this file.  For me, at least, building the Icon.icns file was the hardest and most time-consuming part of this project.

 iconcomposer

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The second item in Project.app/Contents/Resources is an item called "Project".  It's actually a copy of the Microsoft Remote Desktop Connection client:

 

projectinfo

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I've also pasted a custom icon into the Get Info window - this icon should match the one in Icon.ics.  This is needed because when this instance of the RDC app is launched, we want it to have a unique icon that matches the application that is running.  If we did not paste a custom icon, every instance would share the standard Microsoft Remote Desktop Connection icon.

Now, lets return to the MacOS directory.  In an application bundle, this directory contains the actual executable for the bundle and is typically named the same as the bundle (minus the extension). In this case, the executable is named "Project", and is an executable shell script:

 

#!/usr/bin/perl -w
#
#
#       Terminal Services launch script for Microsoft Applications
#       this version by Greg Neagle, Walt Disney Animation Studios
#       

use strict;
use File::Basename;

my $macosdir = dirname $0;
my $contentsdir = dirname $macosdir;

# put the DNS name or IP address of your terminal server here
my $RDCHOST = "ms_term_farm.fas.fa.disney.com";

# put the name of your organization here
my $ORGNAME = "Disney Animation";

#put your Active Directory domain here
my $DOMAIN = "FAS";

# can we ping the RDC host?
my $RDCHOSTavailable = `/sbin/ping -c1 -t1 $RDCHOST 2>/dev/null | /usr/bin/grep "1 packets received"`;
chomp $RDCHOSTavailable;

# If terminal server is unpingable, warn the user
unless ($RDCHOSTavailable) {
        `/usr/bin/osascript<<EOD;
display dialog "The Remote Windows server seems to be unavailable." & return & "Make sure you are on the $ORGNAME network." with icon 1 buttons {"OK"} default button 1
EOD`;
        exit;
}

# get the current username; if your OS X user accounts aren't the same as your AD user accounts,
# you might want to change this to my $USER = ""; so the user has to enter their AD name.
my $USER    = $ENV{USER};

# get the program name; this is the name of the executable
my $PROGRAM = $0;
$PROGRAM =~ s/.*\///;

# find our embedded copy of the RDC client, which we've renamed to the same name as the executable
my $RDCapp = "$contentsdir/Resources/$PROGRAM";

# based on the name of the executable, figure out our Windows application path
# change these to reflect the paths on your terminal server and the applications
# you support
my %APP= ();
$APP{Word}           = 'C:\Program Files\Microsoft Office\Office11\winword.exe';
$APP{Excel}          = 'C:\Program Files\Microsoft Office\Office11\excel.exe';
$APP{InternetExplorer} = 'C:\Program Files\Internet Explorer\iexplore.exe';
$APP{PowerPoint}     = 'C:\Program Files\Microsoft Office\Office11\powerpnt.exe' ;
$APP{Visio}          = 'C:\Program Files\Microsoft Office\Visio11\visio.exe';
$APP{Project}        = 'C:\Program Files\Microsoft Office\Office11\winproj.exe';
$APP{WindowsDesktop}        = '';

# build an RDC connection document
my $RDC_file_contents = <<EOF;
screen mode id:i:1
startdisplay:i:0
desktop size id:i:2
desktopwidth:i:1024
desktopheight:i:768
autoshowmenu:i:1
desktopallowresize:i:1
session bpp:i:15
winposstr:s:0,3,0,0,800,600
auto connect:i:0
full address:s:$RDCHOST
compression:i:1
rightclickmodifiers:i:4608
altkeyreplacement:i:0
audiomode:i:0
redirectdrives:i:1
redirectprinters:i:0
username:s:$USER
domain:s:$DOMAIN
alternate shell:s:$APP{$PROGRAM}
shell working directory:s:
preference flag id:i:3
disable wallpaper:i:0
disable full window drag:i:0
disable menu anims:i:0
disable themes:i:0
disable cursor setting:i:0
bitmapcachepersistenable:i:1
EOF

# write out the RDC connection document
open RDC, ">/tmp/RDC_${USER}_${PROGRAM}_temp";
print RDC "$RDC_file_contents";
close RDC;

# launch our embedded copy of the RDC app and give it the RDC connection document
system "open -a \"$RDCapp\" /tmp/RDC_${USER}_${PROGRAM}_temp";

The script is somewhat universal in that it can be used for multiple applications; it determines which application to launch based on its own name.  This script must be executable.


The finished product

You now should have a double-clickable application that puts an informational icon in the Dock, and connects to your terminal server and launches the desired session. 

How does it work?  You double-click the icon.  The script at Project.app/Contents/MacOS/Project runs.  It creates a Remote Desktop Connection document, then launches the embedded copy of the RDC application and passes it the connection document. 

Multiple versions of this application bundle can be created (which, of course, is the whole point), each pointing to a different application hosted on your terminal server.  Users simply double-click the application they want, just as if it were a Mac application installed locally.

windowsapps

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Below you can see MS Project, MS Visio, and MS IE all running in separate terminal server sessions, and each session has an appropriate icon in the Dock.

desktop

 

The goal was to provide users with an easy-to-understand method to simultaneously connect to multiple Windows applications hosted on a Windows Terminal Server.  This solution, while not perfect, accomplishes just that.

To help you get started with your own version of this solution, I've compiled some resources here. 

Last Updated ( Thursday, 03 January 2008 )
Comments