views:

1444

answers:

8

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:

.NET:

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...

+2  A: 

This is the main one I heard of a long time ago on .NET Rocks. I never really got a change to try it out though

http://www.remotesoft.com/linker/

Jacob Adams
link seems to be dead
Simon
I just tried it. It worked fine for me.
Jacob Adams
+5  A: 

FWIW

Mono has had a linker for quite a while.

Here is an example of how to use mkbundle.

Sam Saffron
As good as the linker is :), it quite doesn't solve the particular issue here. Mono's Linker is a managed one, which only works on managed assemblies.
Jb Evain
Well, then check out mkbundle--http://linux.die.net/man/1/mkbundle.
supercheetah
sambo99, have you had any experience with it?
Robert P
@Robert, nope sorry
Sam Saffron
+2  A: 

Never used it, but I've heard you can do similar things with .NET Reactor

Lurker Indeed
+3  A: 

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

Client profile:

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
Nir
+27  A: 

The case of the Mono Linker.

I can't talk much about the other pieces of software that are listed here, but as the author of the Mono Linker, I can tell what it does and what it does not.

The Mono Linker is only a managed linker, so by definition, it takes assemblies, and removes what's not necessary for a program to run. It doesn't merge assemblies all together, and it doesn't make a native program out of them.

There's a Mono.Merge clone of ILMerge, but it's not complete, and its author is not maintaining it. To generate a native program containing both the Mono runtime and assemblies, Mono provides the mkbundle tool.

Also, as it is only a managed tool, which is altering assemblies, if you give it strong named assemblies, and that you don't have the private keys to sign them back, you'll have troubles running those assemblies.

I wrote a couple of blog posts about the linker:

About our experience with the Linker. The Linker is currently used in two parts of the Mono project. It's used to generate the assembly that we distribute for people to embed our C# compiler, Mono.CSharp.dll. You can watch Miguel's presentation at the PDC, which describes how we do that. It's pretty straightforward, and it's a basic usage of the Linker, which is a customizable tool, and it's pretty easy to write custom steps for it.

A more complex use of the Linker is the way we create our Moonlight assemblies. Moonlight being our implementation of Silverlight, the assemblies are a subset of the desktop assemblies. So we link our desktop assemblies to reduce their sizes, and using custom steps, we're transforming the public API to match Silverlight's.

So yeah, the Linker has some pretty rough edges, such as the command line interface for instance, or the fact that you have to really know what you're doing, or you may end up with some weird assemblies, but all in all, it works really well for us.

Jb Evain
+10 for being cool and writing the mono linker :)
Sam Saffron
the linker is also used for Monotouch to get around the fact that Apple won't allow (byte code) interpreters and virtual machines to be installed on the iphone
Matthew Lock
Matthew: well, not really. The linker is used in MonoTouch to reduce the size of the final application. It's the AOT compiler that circumvents the JIT limitation
Jb Evain
A: 

There is a great article on CodeProject that talks about some of the "linkers" and how they work.

http://www.codeproject.com/KB/dotnet/internals_native.aspx

Dana Holt
+2  A: 

I was arguing ( under my pen name "Mr Analogy") the need for a linker on Joel's forum for a while before he wrote that article. The proliferation of linkers seems to have justified my concern (sadly).

http://www.thinstall.com/

From folks I've talked to, it's fairly well regarded, although last I checked the licensing was onerous ($2k/year per app licensing). They seem to be targeting IT shops rather than sw developer. The fact that you can't find pricing on their site suggests (to me) that it's expensive.

Clay Nichols
+2  A: 

http://www.xenocode.com/

This is what we use. So far, after a year or to of somewhat limited use (maybe 500 installations in the wild), zero problems.

And it's pretty reasonably priced. They have some more expensive full virtualization software (that bundles your app with other apps and even an O/S). But we didn't need all of that. Our cost a year or so ago was $400.I think it's a bit more expensive now but much less than Thinstall.

And they have great demos you can download, like IE 8. No install required.

Clay Nichols