The State of Linkers for .NET apps (aka “Please Sir, May I have a Linker” edizione 2009)

Molte persone qui hanno probabilmente familiarità con uno dei post più popolari di Joel Spolsky , Please Sir, May I Have a Linker , dove grida per un modo per rimuovere le dipendenze dal framework .NET in modo da poter sviluppare un’applicazione stand-alone e venduto.

Jason Zander del team di sviluppo di Visual Studio, al momento, ha risposto con le sue opinioni sull’argomento , sostenendo che l’argomento è in qualche modo discutibile: la capacità di correggere i problemi di sicurezza nel runtime (tra gli altri punti) era la loro principale preoccupazione. Nel complesso, il piccolo overhead è valsa la pena.

Avanti veloce al 2009. Ci sono alcuni gruppi là fuori che affermano di avere dei linker C #. (Jason Zander ha anche detto a se stesso che non ci sarebbe voluto molto per implementarlo.) Invece del simpatico download da decine di mega di .NET 1.0, ora abbiamo un enorme programma di installazione .NET 3.5 completo multipiattaforma da 200-300 mb che contiene versioni di .NET per x86, x64 e ia64. I suggerimenti di Microsoft per ridurre le dimensioni del runtime includono:

  • Disimballare il ridistribuibile, rimuovere le piattaforms di destinazione che non si desidera e rimetterlo insieme
  • Usa il bootstrapper web che scarica solo le librerie per la tua piattaforma
  • Utilizzare il programma di installazione del profilo client (nuovo alla fine del 2008) che ha librerie limitate e funziona solo per x86

A peggiorare le cose, a quanto ho capito (correggimi se ho torto) il profilo del cliente non si registra nemmeno con Windows avendo installato .NET 3.5. Ciò significa che se sul computer sono installate più applicazioni client .NET 3.5, nessuna si vedrà e il runtime verrà reinstallato ancora e ancora!

Non so davvero cosa stia pensando Microsoft. Anche supponendo che l’installazione del caso peggiore sia per una piattaforma di destinazione (ad esempio, x64) e solo quelle librerie devono essere incluse, stai ancora guardando verso l’alto di 60 mb di overhead sulla tua app. Anche una delle applicazioni .NET più conosciute, Paint.NET, era piena di difficoltà nell’installare l’applicazione a causa delle enormi dipendenze .NET. Se hanno problemi a distribuire un’applicazione gratuita, e il resto del mondo? Alla fine, hanno dovuto creare un bootstrapper che abbia installato Microsoft Installer 3.1, il bootstrap di runtime .NET e tutte le altre loro libra dipendenti prima che potessero installare la propria applicazione.

Quindi, riguardo. Un linker. Esistono cose buone o uno strumento che rende semplicemente ansible creare un’applicazione C # senza richiedere all’utente l’installazione del massivo runtime .NET?

Aggiornamento: quindi, sembra che ci siano un paio di opzioni:

Mono:

  • Mono ha il suo linker . Dalla risposta in basso, sembra che funzioni abbastanza bene.

.NETTO:

  • Xenocode sembra essere uno che è disponibile e funziona.
  • Thinstall è un altro che è stato raccomandato, ed è di VMware.
  • C’è un altro linker di Remotesoft . Lo fatturano come un “obfuscator”. Qualche idea lì?
  • Trovato un altro da Rustemsoft chiamato Skater .NET Obfuscator . Qualcuno ha familiarità con loro?
  • È stato anche suggerito ILmerge di Microsoft ; sembra che esegua solo parte del compito (cioè, unendo le librerie, non estraendo i bit inutilizzati).

Sembra che gli strumenti Mono si stiano usando; che ne dici degli strumenti basati su .NET? Qualche altra esperienza con loro, o dovremo aspettare che Microsoft lo spinga a tutti? Rabbrividisco a pensare a quanto tempo ci vorrà affinché .NET 4.0 venga messo fuori …

Il caso del Mono Linker .

Non posso parlare molto degli altri software elencati qui, ma come autore del Mono Linker, posso dire cosa fa e cosa no.

Mono Linker è solo un linker gestito, quindi per definizione prende gli assembly e rimuove ciò che non è necessario per l’esecuzione di un programma. Non unisce gli assembly tutti insieme e non ne crea un programma nativo.

C’è un clone Mono.Merge di ILMerge, ma non è completo, e il suo autore non lo sta mantenendo. Per generare un programma nativo contenente sia il runtime Mono sia gli assiemi, Mono fornisce lo strumento mkbundle .

Inoltre, poiché è solo uno strumento gestito, che sta modificando gli assembly, se gli si assegna un assembly con un nome forte e non si dispone delle chiavi private per ricollegarlo, si avranno problemi durante l’esecuzione di tali assembly.

Ho scritto un paio di post sul blog sul linker:

  • Una presentazione del linker
  • Un uso combinato del linker e mkbundle

Sulla nostra esperienza con il Linker. Il Linker è attualmente utilizzato in due parti del progetto Mono. Viene utilizzato per generare l’assembly che distribuiamo affinché le persone incorporino il nostro compilatore C #, Mono.CSharp.dll. Puoi vedere la presentazione di Miguel al PDC, che descrive come lo facciamo. È piuttosto semplice, ed è un uso basilare del Linker, che è uno strumento personalizzabile, ed è abbastanza facile scrivere passi personalizzati per questo.

Un uso più complesso del Linker è il modo in cui creiamo i nostri assemblaggi di Moonlight . Moonlight essendo la nostra implementazione di Silverlight, gli assembly sono un sottoinsieme degli assembly desktop. Quindi colleghiamo i nostri assembly desktop per ridurne le dimensioni e, utilizzando i passaggi personalizzati, trasformiamo l’API pubblica in modo che corrisponda a Silverlight.

Quindi sì, il Linker ha dei bordi piuttosto grezzi, come l’interfaccia della riga di comando, per esempio, o il fatto che devi sapere davvero cosa stai facendo, o potresti finire con qualche strano assemblaggio, ma tutto sumto, funziona davvero bene per noi.

FWIW

Mono ha avuto un linker per un bel po ‘.

Ecco un esempio di come usare mkbundle.

http://www.xenocode.com/

Questo è ciò che usiamo. Finora, dopo un anno o un uso piuttosto limitato (forse 500 installazioni in natura), zero problemi.

Ed è piuttosto a prezzi ragionevoli. Dispongono di un software di virtualizzazione completo più costoso (che raggruppa la tua app con altre app e persino un O / S). Ma non avevamo bisogno di tutto questo. Il nostro costo circa un anno fa era di $ 400. Penso che sia un po ‘più costoso ora ma molto meno di Thinstall.

E hanno grandi demo che puoi scaricare, come IE 8. Nessuna installazione richiesta.

Il profilo del client si registra con Windows, ma in un modo speciale poiché non si desidera confondere una macchina con un solo profilo client con una macchina con la versione 3.5 completa.

Profilo del cliente:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\DotNetClient\v3.5\Install 

Completa .net 3.5:

 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5\Install 

Questo è il principale che ho sentito molto tempo fa su .NET Rocks. Non ho mai avuto davvero un cambiamento per provarlo però

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

Mai usato, ma ho sentito che puoi fare cose simili con .NET Reactor

Stavo discutendo (sotto il mio pseudonimo “Mr Analogy”) la necessità di un linker sul forum di Joel per un po ‘prima che scrivesse quell’articolo. La proliferazione di linker sembra aver giustificato la mia preoccupazione (purtroppo).

http://www.thinstall.com/

Da gente con cui ho parlato, è abbastanza ben considerato, anche se l’ultima volta che ho controllato la licenza era onerosa ($ 2k / anno per licenza app). Sembrano rivolti ai negozi IT piuttosto che agli sviluppatori sw. Il fatto che non sia ansible trovare prezzi sul loro sito suggerisce (per me) che è costoso.

C’è un grande articolo su CodeProject che parla di alcuni “linker” e di come funzionano.

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