[c#] The State of Linkers for .NET apps (aka “Please Sir, May I have a Linker” 2009 edition)
Many people here are probably familiar with one of Joel Spolsky most popular blog posts, Please Sir, May I Have a Linker, where he cries out for a way to remove dependencies on the .NET framework so a stand-alone application can be developed and sold.
Jason Zander of the Visual Studio development team, at the time, replied with his views on the topic, arguing that the topic is somewhat moot - the ability to fix security problems in the runtime (among other points) was their chief concern. Overall, the small overhead was worth it.
Fast forward to 2009. There's a few groups out there now claiming to have C# linkers. (Jason Zander even said himself that it wouldn't take much to implement one.) Instead of the cute, dozen-so meg download of .NET 1.0, we now have a massive 200-300 mb cross-platform complete .NET 3.5 installer that contains versions of .NET for x86, x64, and ia64. Microsoft's suggestions to decrease the runtime size include:
- Unpack the redistributable, remove the target platforms you don't want, and put it back together
- Use the web bootstrapper that only downloads the libraries for your platform
- Use the Client Profile installer (new as of late 2008) which has limited libraries and only works for x86
To make matters worse, as I understand it (please correct me if I'm wrong) the client profile don't even register with windows as having .NET 3.5 installed. This means if multiple .NET 3.5 client applications are installed on the computer, none will see each other and the runtime will be re-installed again and again!
I really don't know what Microsoft is thinking here. Even assuming the worst case install will be for one target platform (eg, x64) and only those libraries need to be included, you're still looking at upwards of 60 mb overhead on your app. Even one of the most well known .NET apps, Paint.NET, was fraught with Difficulties installing the application because of the massive .NET dependencies. If THEY have problems distributing a free app, what about the rest of the world? In the end, they had to Make a bootstrapper that installed Microsoft Installer 3.1, the .NET runtime bootstrapper, and all their other dependent libraires before they could install their own application.
So how about it. A linker. Do any good ones exist - or a tool that simply makes it possible to build a C# application without requiring that the user install the massive .NET runtime?
Update: so, it looks like there's a couple of options:
- Mono has its own linker. From the answer below, it looks like it works pretty well.
- Xenocode seems to be one that's available and works.
- Thinstall is another that was recommended, and it's by VMware.
- There's another linker by Remotesoft. They bill it as an 'obfuscator'. Any thoughts there?
- Found another by Rustemsoft called Skater .NET Obfuscator. Anyone familiar with them?
- ILmerge by Microsoft was also suggested; this looks like it only performs part of the task (ie, merging libraries, not stripping out unused bits).
It looks like the Mono tools are getting use; how about the .NET based tools? Any other experience with them, or are we just going to have to wait for Microsoft to push it 3.5 out to everyone? I shudder to think how long it'll take for .NET 4.0 to be put out...
There is a great article on CodeProject that talks about some of the "linkers" and how they work.
Client profile registers with Windows, but in a special way since you don't want to confuse a machine with only client profile with a machine with the full .net 3.5
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\DotNetClient\v3.5\Install
Full .net 3.5:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5\Install
Never used it, but I've heard you can do similar things with .NET Reactor