Back when Silverlight 1.1 (the predecessor to today’s Silverlight 2 release) was first announced at the Mix ‘07 keynote, I remember being fascinated by the cross-platform .NET Framework aspect of it. As a cross-platform browser plug-in, Silverlight has the potential to enable web developers to design and develop an application with .NET and have it run & look the same everywhere. Would this be the holy grail of web programming? Well, that’s not for me to decide, but no matter how you cut it, Silverlight 2 is a very very cool technology!
At Mix ‘07, one of the cooler demos I remember seeing was Scott Guthrie’s keynote where he debugged a Silverlight application running on a Mac. I found it fascinating that this type of intricate programming communication could work not only across remote machines, but across different operating systems! I knew that you could debug code on a remote server using Visual Studio, but seeing it work against a Mac definitely caught my attention.
At first, I though, why is this even important? With Silverlight, I should be able to write once and run everywhere. If I test and debug on Windows, it should just work over on the Mac, right? Well, it’s fun to believe in marketeering claims like that, but everyone knows you need to test on any environment before you deploy to it!
While there are some minor Silverlight differences between Windows and the Mac, there are other reasons for needing to be able to test on a Mac too. As an application developer, you might want your program to do something different depending on which OS it is running on. There would be no way to test that type of code without this type of remote debugging tool. (I have a silly example that demonstrates this below.)
Not long after Silverlight 1.0 came out, I got a Mac Book Pro. In my experience as a field evangelist who frequently demos Silverlight, it always turns heads when you demo it actually running on a Mac. One of the first things I did when I got my MBP up and running was to try and configure the remote debugging feature in what was then the Silverlight 1.1 alpha. While it turned out to be a relatively easy thing to configure and setup, it was no picnic finding all of the documentation and “gotchas” on how to do it. I chocked that up as typical alpha documentation.
When the Silverlight 2 betas (1 & 2) came out, the process for setting up remote debugging on a Mac changed slightly for each one. Not only that, it actually was harder to find the documentation on how to do it. I ended up relying on a couple of random blog posts I came across on Live Search & Google to figure it out. If your search turns up any of these links, know that they are now obsolete:
Old 1.1 Alpha Way of Doing Things:
Old Silverlight 2 Beta 1 Way of Doing Things:
The only official documentation I found for Beta 2 was here in one of the Silverlight readme files. The good thing is that now the official Silverlight 2 SDK has a good walkthrough. While the process hasn’t changed with the released version of Silverlight 2, I thought I’d cover it here along with some sample code you can use to try it at home. I’m also a relative newbie with the Mac OS, so there are some basic steps I’ll cover here that I’m embarrassed to admit took me a while to figure out. Hopefully they help the next Mac newbie along.
The Application: PC or Mac?
First off, I’ve got a simple sample application that will tell the user if they’re a right-clicka or an iBook flippa. Using Expression Blend 2.0 SP1, I put together some XAML that displays a button on the screen that says “PC or Mac?”.
When the user clicks the button, the handler will retrieve the Operating System platform and version out of the Environment collection and then update a TextBlock element with the values to report back to the user what OS they are using.
You can see that C# snippet here:
1: private void PCorMacButton_Click(object sender, RoutedEventArgs e)
3: string platform = Environment.OSVersion.Platform.ToString();
4: string version = Environment.OSVersion.Version.ToString();
6: if (platform == "Win32NT")
8: ResultsTextBlock.Text = "I'm a PC!";
10: else if (platform == "MacOSX")
12: ResultsTextBlock.Text = "I'm a Mac!";
15: OSVersionTextBlock.Text = "You're running: " + platform + " Version: " + version;
Clicking that button on my PC results in this:
Okay… that looks simple enough. But now how do I test whether I’ll get back the proper value on the Mac so that it will display “I’m a Mac!”? This is where the remote debugging feature comes in. By using remote debugging, I can check the value returned by Environment.OSVersion.Platform to verify that it will match one of the comparisons in the “if” statement. (Please bare with me. I know this is a contrived scenario, but I think you get the point. :)
Deploy The Application
During regular development, you are likely using F5 to run your Silverlight application from Expression Blend or Visual Studio 2008. This fires off an instance of the browser that loads the static default.html page hosting the Silverlight application from the file system or, the ASP.NET Development Server if you’re hosting it in an ASP.NET web form. In order for the Macintosh to run your Silverlight application, you need to make it available by deploying it either to a web server accessible by the Mac, or doing a file copy to a local folder on the Mac.
I’ve posted my sample application on Skydrive for you to test drive this with:
On my Windows machine, I configured a virtual directory in the Internet Information Server (IIS) web server to host the application. To deploy the application, compile it in Visual Studio, then copy the contents of the /bin/debug folder to the virtual directory. If you look at the /bin/debug folder of my sample application in Visual Studio’s Solution Explorer, you can see that Visual Studio auto-generated a static “default.html” file to host the Silverlight application. This is the file you want to point your browser at to view the Silverlight application.
With the application deployed to IIS, as long as the Macintosh computer is on the same network as the Windows machine, the Mac should be able to hit the URL to the virtual directory using the Windows machine’s IP address. If setting IIS up for the first time, you might need to open the appropriate ports in the Windows Firewall in order to allow remote machines to access it.
Alternatively, you can copy the contents of the /bin/debug folder to a local folder on the Mac. Then point the Safari or Firefox browser on the Mac at the default.html file.
Once you have verified that you can access the Silverlight application from a browser on the Macintosh, you are ready to set up remote debugging.
Setting Up Remote Debugging
According to the Walkthrough in the SDK, the prerequisites for remote debugging are:
A computer running Windows with Visual Studio 2008 SP1 and the Silverlight Tools for Visual Studio 2008 installed.
A Macintosh computer that has the Silverlight developer runtime installed.
A network connection on both computers.
A way to transfer files between the Windows and Macintosh computers.
In my case, I am running Windows XP in a virtual machine on my Mac Book Pro using VMWare’s Fusion. The virtual machine can communicate with the Mac and share files via the virtual network stack. (You can also use Parallels to run Windows in a virtual machine on the Mac.) I have also set up remote debugging between two physical machines on the same network. I find it is easier to run all of my development and debugging demos on one physical box then to lug two laptops around everywhere. However, you will be be better off developing on a real PC as running Visual Studio & Expression Blend in a virtual machine can be a bit sluggish.
If you have installed the Silverlight Tools for Visual Studio 2008, then you already have everything you need on your developer PC. On the Mac, you will need to install the Silverlight 2 Developer Runtime for the Mac. This runtime contains a proxy service that runs on the Macintosh. The proxy helps the remote debugger on Windows identify local processes running Silverlight applications on the Mac.
The Silverlight 2 Developer Runtime for the Mac will install the Silverlight 2 browser plug-in on the Mac as well as the proxy service. It will upgrade and replace any previous versions of Silverlight you have on the machine (including 1.0 and any of the 2.0 betas). Therefore, it is the only install you need on the Mac machine you are testing with. The installation dialog hints at the next step in the process on the Mac. (Click the thumbnails below for a larger view of what the installation dialogs say.)
Remote debugging occurs over an SSL-encrypted TCP channel between the debugger and the target computer. Configuration must be performed on both the Macintosh computer and the computer running Windows in order to set up the TCP port and private/public key pair.
Configuring the Macintosh
The next step is to configure the proxy service on the Macintosh. You do this by launching the “Silverlight Debugging Configuration.app” application on the Macintosh. The configuration application should be in the /Applications directory on the Macintosh as pictured below:
The configuration application launches with the dialog below. Simply click the “Generate New Configuration” button, choose a password for the encryption key, and finally click the “Generate PC Configuration” button. It’s as simple as that!
When you click the “Generate PC Configuration” button, the tool generates an executable (.exe) file that you contains the password protected encryption key needed on the PC to talk back to the proxy on the Macintosh. I typically just take the default location, which will place the generated .exe file on the Macintosh desktop. Below is the confirmation dialog you see to let you know the file has been successfully generated:
The next step is to copy the .exe file from the Mac to the Windows machine. Since I am running Windows in a virtual machine, Fusion let’s me set up sharing folders with the host (Mac OS), enabling Windows to see the Mac desktop folder. I end up running it directly from the sharing folder without even copying it. If you are on a different physical machine, it is up to you to copy the file across the network or “sneaker net” it with a USB key. 🙂
Configuring the PC
This is the easiest part. Just run the .exe file on the PC. It will prompt you for the password you created on Mac.
After it runs, click “Ok” on the confirmation box that pops up, and you’re ready to roll!
Let’s Start Debugging!
First, start the Silverlight application on the Macintosh that you wish to debug. (Note: The URL is pointing to the IP address of the Windows machine. In my scenario, this is the IP addressed assigned to my virtual machine by Fusion.)
On the Windows machine, open the Silverlight project in Visual Studio. Then, on the “Debug” menu, select “Attach to Process…”
In the Transport drop-down list, select “Silverlight Remote Cross-Platform Debugging”.
In the Qualifier combo box, enter the fully-qualified domain name or IP address of the Mac. This one hung me up for a while when I first got my Mac, since I didn’t know where to find the IP address. (Hint: Under “System Preferences” on the Apple menu, double-click the “Network” icon and you will see the IP address of your Mac.)
As soon as you enter the IP address of the Mac, the “Available Processes” window is populated with a list of processes running on the Macintosh. In the image above, you can see that both the Safari and Firefox processes have “Silverlight” displayed in the “Type” column. This means that those processes are running an instance of Silverlight. The remote debugging tool can only attach to processes of type “Silverlight”. You can debug into a Silverlight application running in either Safari or Firefox on the Mac.
If you forgot to start the Silverlight application in the browser before launching the tool, you might see the browser process listed without “Silverlight” in the type column. In this case, load the Silverlight application in the browser on the Mac, then click the “Refresh” button in the “Attach to Process” window. If that doesn’t work, you may need to restart the browser entirely on the Mac and then hit “Refresh” on the PC.
Select the process you want to debug and then click “Attach”. If the planets have aligned properly, the Visual Studio debugger is now attached to the target process on the Mac! You can now use Visual Studio to do all the regular debugging stuff you know and love such as set breakpoints, step through code, and examine the call stack.
Now, let’s go back to the contrived scenario I set up in my sample application. We want to set a break point to check and see what value we get back for the OS version to see if it will match up with the value that triggers the “if” statement to display “I’m a Mac!”. Go ahead and click the “PC or Mac?” button in the browser on the Mac and you should see the following happen in Visual Studio on your PC:
As you can see in the image above, the debugger has hit a breakpoint. In the Watch pane, we can see that the value returned by Environment.OSVersion.Platform.ToString() is “MacOSX”, which does indeed match the value the code tests for in the “if” statement!
While the debugger is stopped on a breakpoint, if you view the browser on your Mac, you will see that it is “stuck” waiting for the UI operation to return. If you move the mouse on the Mac, you will get the “busy beach-ball” symbol. Once you release the debugger from the breakpoint by pressing F5 to continue, the code continues executing on the Mac, and the screen displays the following:
The debugger is still attached at this point until you stop it manually in Visual Studio or close the browser on the Mac.
Summary & Conclusion
If you’ve made it all the way down here to the end of this post, you’ve learned that it is indeed possible to remotely debug a Silverlight application running on a Macintosh computer. This is a very powerful feature to have in your toolbox when building Silverlight applications which will run on different platforms. While the instructions might seem long in the tooth, it is very easy to set this up!
For all of the information you need to get started on Silverlight development, visit: http://silverlight.net/getstarted
At that site, you will find an aggregation of all the links to the tools, runtimes, and the SDK. Happy Silverlight programming to ya!