Windows .NET Development on Mac OSX

I use Windows at work so for some variety I have moved to a Mac at home. The 2010 Mac Mini is a decent little machine with the RAM upgraded to 4GB.

For Windows development you need Visual Studio, which means running Windows on your Mac. Bootcamp is one way of doing this, but then you lose all the benefits of OSX as your host OS. The secret is of course Parallels Desktop which allows you to run Windows virtualized on your Mac.

Using Parallels Desktop for Windows Development

It took a couple of tries to get this working decently.

  • Install Parallels Desktop
  • Get a Windows 7 32bit ISO image from MSDN (or a retail copy of course)
  • Set up a new Virtual Machine, specifying your Windows 7 ISO to install from

Screen shot 2010-12-16 at 9.19.16 PM.png

  • Select “Like a Mac” so the application integration gets automatically set up
  • IMPORTANT: For best performance, place the virtual machine on a separate drive. I get good results with an external USB2.0 Hard Drive but Mac Pro owners can put this on an internal disk. The built in hard disk of the Mac Mini is only 5400rpm which will be a real bottleneck when running OSX and Windows off the same disk. (You can of course use Parallels to run Windows off your Bootcamp partition – this will be slow too if the partition is on the same physical disk as OSX).
  • Allow Parallels to install Windows automatically. It will select the default settings during installation and input your product key. You will eventually end up with a nice Windows 7 desktop inside a Parallels window.

Screen shot 2010-12-16 at 9.27.33 PM.png

  • Parallels will automatically map your Desktop, Documents, Pictures, Music and Download folders to Windows’s equivalents, meaning you will see the same files on the Mac and Windows desktops.
  • Install Visual Studio 2010. You can mount the ISO in the Parallels Virtual Machine settings. A couple of restarts (of the VM) later and it is installed.
  • You will notice that running applications in the Windows VM show up in the Dock. You can even right click and pin the applications to the Dock. Parallels will start the virtual machine and launch the application.
  • Click the Coherence button in Parallels and Windows will be integrated with OSX. Launching Visual Studio 2010 from your pinned dock icon will give you Visual Studio 2010 with the same appearance and window behaviour as a standard Mac app:

Screen shot 2010-12-16 at 9.34.30 PM.png

  • You are now ready to develop Windows applications from OSX. Parallels has GPU acceleration so even WPF applications are not too bad.

Advanced Tips

  • Give the Windows 7 Virtual Machine enough RAM, but not enough that OSX will start paging. With 4GB of RAM, you can afford to give the VM 1GB. Remember: you are only going to run Visual Studio on Windows 7. All your other apps; browsers, Photoshop, Skype etc, will run in OSX.
  • Activate the “Pause Windows when no applications are open” setting under Applications in the Windows 7 VM settings. This means that the virtual machine will pause and give the memory back to OSX when no applications are running.
  • Be aware that your Documents folder on Windows is now a network drive, with all the security differences this brings. .NET will be strict about this in some cases (I hit this problem when running a custom content processor for XNA, which cannot be loaded from network drives) If you hit security problems, you need to set the \\.psf\ network drive to FullTrust for .NET. Run this command from a command prompt in Windows and restart Visual Studio:
C:\Windows\Microsoft.NET\Framework\v2.0.50727> CasPol.exe -pp off -m -ag 1.2 -url \\.psf\* FullTrust
  • Make sure that while you backup your Documents folder and Visual Studio projects with Time Machine, don’t backup the drive that the Windows Virtual Machine hard disk is on or you will run out of backup space very quickly. Parallels also has an option to make sure that this does not happen.

 

That upgraded WPF 4.0 Text rendering again

Just to hammer the point home about how important it is to upgrade to .NET 4.0 if you are using WPF, here are some comparison screenshots of the text rendering in WPF 3.5 and 4.0:

wpftext.png

Pay attention to the difference between the text rendering on lines 2 and 3.

Line 2 shows the new Display formatting mode available in WPF 4.0. This renders the text the same way as the rest of Windows – the shape of the font is distorted so that lines fall on pixel boundaries. For small text this should be used for consistency with the rest of Windows or users will most likely complain that your text looks “blurry” (even though it is technically rendered correctly). Large font sizes or high DPI screens can stick to the standard WPF rendering mode.

Line 3 shows what Japanese Windows XP users will see if they use your application as they don’t have Meiryo installed. In WPF 3.5, Asian text is a mess at small font sizes because WPF 3.5 does not support bitmap fonts – instead it scales down the large vector font data in the font file. WPF 4.0 supports bitmap fonts so that Japanese text now is rendered the same way as the rest of Japanese XP.

It is worth being reminded that it took Microsoft themselves to dogfood WPF 4.0 when developing Visual Studio 2010 before these problems were solved.

Evernote has no patience, drops WPF over fixed issues

Much noise has been made about Evernote’s new Windows client. For version 4, they dropped WPF/.NET and released a C++ native application.

They were pretty damning with their reasoning:

Evernote 4 is a major departure from Evernote 3.5 in every way. While 3.5 added tons of great new features, there were some problems we simply couldn’t fix: the blurry fonts, slow startup times, large memory footprint, and poor support for certain graphics cards were all issues that the technology behind 3.5 (Windows .net and WPF) was incapable of resolving. As a result, we ended up chasing down platform bugs rather than adding the great features our users wanted.

So we decided to start over from scratch, with fast, native C++ that we knew we could rely on. As you’ll see, the results are amazing. This new version will set a foundation for rapid improvement.

Evernote 4 is designed to give you a great experience on any computer that you use, whether you’re on a netbook, a five year old Windows XP machine or a super fast top-of-the-line Windows 7 computer.

On our test hardware, Evernote 4 starts five times faster, and uses half the memory of Evernote 3.5.

 

You cannot make statements like “issues that the technology behind 3.5 … was incapable of resolving” without providing more information on the problems they faced and the solutions they tried. For all we know, their Windows client development team could have tripled in size to get the native version out the door.

Evernote 3.5 was a textbook example of reasons to immediately upgrade to .NET 4.0 if you are building WPF applications. Visual Studio’s UI layer is now in WPF, presumably after fixing all these issues.

“The text is blurry”

This is fixed in WPF 4.0, which can render text almost exactly as Windows does if developers request it. The standard behaviour is a DPI-independent accurate representation of the font on the screen (the same way OSX renders text and also the reason why text is “blurry” on Macs).

This is a one-line fix in .NET 4.0, just apply TextOptions.TextFormattingMode=”Display” to your root XAML element. Asian text will also now use bitmap fonts so customers on Japanese XP machines will now get consistent text rendering between your app and their vintage OS (of course Vista/Win7 should be using Meiryo).

“The download size is too large”

The runtime for .NET 3.5 is 65MB or so. .NET 4.0 has reduced this to a 28MB download. Ironically, the Evernote 4.0 installer is 40MB – most likely larger than bundling the .NET 4.0 runtime in the installer of 3.5. Users with .NET 4.0 already installed would have got an even smaller download as the installer would not download the runtime.

Evernote 4.0 appears to include Chromium (the Chrome web browser base), Foxit Reader’s PDF libraries, SQLLite and libxml which could be replaced with the built in Web Browser control, XPS rendering, SQLCE and built in XML libraries of .NET 4.0.

“It uses too much memory”

If your application has hundreds of threads and handles complex local operations, it will require memory. Evernote’s statement about version 4.0 using “half” the memory of the managed 3.5 version is pretty damning considering that the application is not very complicated.

While you may never be able to match the memory consumption of a “native” application in .NET, there are some things you need to know to improve your memory use:

  • Use .NET 4.0 as it has background garbage collection
  • Keep your visual tree small (no endless nested Grids in XAML)
  • Virtualize your ItemControls! This might be the most important issue. You cannot bind a XAML WrapPanel to 1000 images without Virtualization and expect scrolling to be smooth or your memory consumption to be low.
  • Use the ThreadPool and Background Workers instead of manually creating threads. ThreadPool-based tasks intelligently carry out the number of simultaneous tasks based on the number of processor cores you have. Allowing your code to create and infinite number of threads is a recipe for disaster as each thread needs its own stack space of at least 1MB. Ideally use .NET 4.0s new parallel programming and async functions.
  • Read the correct memory numbers in Task Manager (Private Working Set).

“The application is slow to start up”

Managed applications do not have to start slowly. A new application from a VS template will start up instantly – it is when you start adding references to other libraries, interop hooks and modules (for composite apps) that startup time starts dropping. Perhaps the most important thing to do is use NGEN to generate a native version of your application at install time, instead of waiting for the JIT compilation when the user launches the application. The application will slow down when loading modules for the first time if they have not been pre-compiled. There is some great information on improving start up times on MSDN, as usual.

In general, try to show some part of your application immediately. A splash screen might be okay for application start up times of less than a few seconds, but there is no reason why the main window can not be displayed and relevent data start loading in the background. This is mainly a perception issue. If you only show your main window after loading all data that your application could possibly need ever, of course start up will appear to be slow.

Did Evernote even try .NET 4.0?

The .NET development community is waiting for some sort of postmortem from the Evernote team. Most of the above problems would have been solved by upgrading to .NET 4.0 and running some decent profilers on the executable.

Rewriting your application natively will no doubt use less memory and start up faster, but it will also look worse, take longer, be more expensive to develop and your UI will break when high DPI screens start to be used. Portability is not a reason: if you want an application to work on Windows/Mac/Linux/iOS/Android, you write a web application.

If you want an example of an amazing WPF 4.0 application designed for the Windows platform, check out MetroTwit.