ILMerge Best Practices

72

Verwenden Sie ILMerge? Verwenden Sie ILMerge, um mehrere Assemblys zusammenzuführen, um die Bereitstellung von DLLs zu vereinfachen? Haben Sie Probleme mit der Bereitstellung / Versionierung in der Produktion nach dem Zusammenführen von ILMerg-Assemblys festgestellt?

Ich suche nach Ratschlägen zur Verwendung von ILMerge, um die Reibung bei der Bereitstellung zu verringern, falls dies überhaupt möglich ist.

James Pogran
quelle

Antworten:

44

Ich benutze ILMerge für fast alle meine verschiedenen Anwendungen. Ich habe es direkt in den Release-Build-Prozess integriert, sodass ich am Ende eine Exe pro Anwendung ohne zusätzliche DLLs habe.

Sie können keine C ++ - Assemblys mit nativem Code ILMerge. Sie können auch keine Assemblys ILMerge, die XAML für WPF enthalten (zumindest hatte ich damit keinen Erfolg). Zur Laufzeit wird beanstandet, dass die Ressourcen nicht gefunden werden können.

Ich habe eine ausführbare Wrapper-Datei für ILMerge geschrieben, in der ich den Namen der Start-Exe für das Projekt, das ich zusammenführen möchte, und einen Namen für die Ausgabe-Exe übergebe. Anschließend werden die abhängigen Assemblys wiedergegeben und ILMerge mit den entsprechenden Befehlszeilenparametern aufgerufen. Wenn ich dem Projekt neue Assemblys hinzufüge, ist es jetzt viel einfacher. Ich muss nicht daran denken, das Build-Skript zu aktualisieren.

Lamar
quelle
Wie haben Sie diese Release-Build-Integration durchgeführt?
Svish
@Svish - hanselman.com/blog/…
Sean Gough
8
Hier ist eine mögliche Problemumgehung für ILMerge + XAML: richarddingwall.name/2009/05/14/…
scobi
roman.st/Article/ILMerge-and-GeneratedInternalTypeHelper - Eine weitere Problemumgehung für ILMerge + XAML
Prat
2
@ Lamar Könnten Sie diesen Wrapper .exe für ILMerge freigeben?
Florien
41

Einführung

Dieser Beitrag zeigt, wie Sie alle .exe + .dll filesdurch eine einzige ersetzen können combined .exe. Außerdem bleibt die Debugging- .pdbDatei erhalten.

Für Konsolen-Apps

Hier finden Sie die Grundlagen Post Build Stringfür Visual Studio 2010 SP1 unter Verwendung von .NET 4.0. Ich erstelle eine Konsolen-EXE-Datei mit allen darin enthaltenen Sub-DLL-Dateien.

"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards

Grundlegende Hinweise

  • Die Ausgabe ist eine Datei " AssemblyName.all.exe", die alle Unter-DLLs in einer EXE- Datei kombiniert.
  • Beachten Sie das ILMerge\Verzeichnis. Sie müssen entweder das ILMerge-Dienstprogramm in Ihr Lösungsverzeichnis kopieren (damit Sie die Quelle verteilen können, ohne sich um die Dokumentation der Installation von ILMerge kümmern zu müssen) oder diesen Pfad so ändern, dass er auf ILMerge.exe verweist.

Erweiterte Hinweise

Wenn Sie Probleme damit haben, schalten Sie ein Outputund wählen Sie Show output from: Build. Überprüfen Sie den genauen Befehl, den Visual Studio tatsächlich generiert hat, und suchen Sie nach Fehlern.

Beispiel für ein Build-Skript

Dieses Skript ersetzt alle .exe + .dll filesdurch ein einzelnes combined .exe. Außerdem bleibt die Debugging-PDF-Datei erhalten.

Fügen Sie dies zur Verwendung in Ihren Post BuildSchritt unter der Build EventsRegisterkarte in einem C # -Projekt ein und stellen Sie sicher, dass Sie den Pfad in der ersten Zeile so anpassen, dass er auf Folgendes zeigt ILMerge.exe:

rem Create a single .exe that combines the root .exe and all subassemblies.
"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
rem Remove all subassemblies.
del *.dll
rem Remove all .pdb files (except the new, combined pdb we just created).
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp"
del *.pdb
ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb"
rem Delete the original, non-combined .exe.
del "$(TargetDir)$(TargetName).exe"
rem Rename the combined .exe and .pdb to the original project name we started with.
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb"
ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe"
exit 0
Contango
quelle
1
Wie zeigen Sie die Ausgabe von Build? Ich habe ein stilles Problem beim Schreiben der Ausgabe. stackoverflow.com/questions/42301103/…
octopusgrabbus
@octopusgrabbus in Visual Studio, wählen View.. Output, wählen Build, und es zeigt die Kommandozeilen - Ausgabe des Compilers (einschließlich der Schritte oben). Alternativ können Sie diese Befehle in eine .batDatei kopieren und dann in einem DOS-Fenster ausführen, um die Ausgabe anzuzeigen.
Contango
10

Wir verwenden ILMerge für die Microsoft-Anwendungsblöcke. Anstelle von 12 separaten DLL-Dateien haben wir eine einzige Datei, die wir in unsere Clientbereiche hochladen können, und die Dateisystemstruktur ist viel übersichtlicher.

Nach dem Zusammenführen der Dateien musste ich die Visual Studio-Projektliste bearbeiten, die 12 separaten Assmeblies entfernen und die einzelne Datei als Referenz hinzufügen, da sich sonst beschweren würde, dass die bestimmte Assembly nicht gefunden werden konnte. Ich bin mir nicht sicher, wie dies nach der Bereitstellung funktionieren würde. Es könnte sich lohnen, es auszuprobieren.

Chirurgischer Kodierer
quelle
7

Ich weiß, dass dies eine alte Frage ist, aber wir verwenden ILMerge nicht nur, um die Anzahl der Abhängigkeiten zu reduzieren, sondern auch, um die "internen" Abhängigkeiten (z. B. Automapper, Restsharp usw.) zu verinnerlichen, die vom Dienstprogramm verwendet werden. Dies bedeutet, dass sie vollständig abstrahiert sind und das Projekt, das das zusammengeführte Dienstprogramm verwendet, nichts über sie wissen muss. Dadurch werden die erforderlichen Referenzen im Projekt erneut reduziert und es kann bei Bedarf eine eigene Version derselben externen Bibliothek verwendet / aktualisiert werden.

Mightymuke
quelle
3

Wir verwenden ILMerge für einige Projekte. Die Web Service Software Factory erzeugt beispielsweise etwa 8 Assemblys als Ausgabe. Wir führen alle diese DLLs zu einer einzigen DLL zusammen, sodass der Service-Host nur auf eine DLL verweisen muss.

Es macht das Leben etwas einfacher, aber es ist auch keine große Sache.

Esteban Araya
quelle
3

Wir hatten das gleiche Problem beim Kombinieren von WPF-Abhängigkeiten ... ILMerge scheint sich nicht mit diesen zu befassen. Costura.Fody hat jedoch perfekt für uns funktioniert und ungefähr 5 Minuten gebraucht, um loszulegen ... eine sehr gute Erfahrung.

Installieren Sie einfach mit Nuget (wählen Sie das richtige Standardprojekt in der Package Manager-Konsole aus). Es stellt sich in das Zielprojekt vor und die Standardeinstellungen haben sofort für uns funktioniert.

Es führt alle mit "Copy Local" = true gekennzeichneten DLLs zusammen und erzeugt eine zusammengeführte EXE-Datei (neben der Standardausgabe), deren Größe gut komprimiert ist (viel weniger als die Gesamtausgabegröße).

Die Lizenz ist MIT, da Sie sie nach Bedarf ändern / verteilen können.

https://github.com/Fody/Costura/

rexall
quelle
3

Beachten Sie, dass Sie für Windows-GUI-Programme (z. B. WinForms) den Schalter / target: winexe verwenden möchten .
Der Schalter / target: exe erstellt eine zusammengeführte Konsolenanwendung .

Dlchambers
quelle
1

Beim Zusammenführen von DLLs mit Ressourcen im selben Namespace sind Probleme aufgetreten. Beim Zusammenführen wurde einer der Ressourcennamensräume umbenannt, sodass die Ressourcen nicht gefunden werden konnten. Vielleicht machen wir dort einfach etwas falsch und untersuchen das Problem immer noch.

Patrick
quelle
1

Ich beginne gerade damit, ILMerge als Teil meines CI-Builds zu verwenden, um viele feinkörnige WCF-Verträge in einer einzigen Bibliothek zu kombinieren. Es funktioniert sehr gut, aber die neue zusammengeführte Bibliothek kann nicht einfach mit ihren Komponentenbibliotheken oder anderen Bibliotheken, die von diesen Komponentenbibliotheken abhängen, koexistieren.

Wenn Sie in einem neuen Projekt sowohl auf Ihre ILMerged-Bibliothek als auch auf eine Legacy-Bibliothek verweisen, die von einer der Eingaben abhängt, die Sie ILMerge gegeben haben, können Sie keinen Typ aus der ILMerged-Bibliothek an eine Methode in übergeben die Legacy-Bibliothek ohne irgendeine Art von Typzuordnung (z. B. Automapper oder manuelle Zuordnung). Dies liegt daran, dass die Typen nach dem Kompilieren effektiv mit einem Baugruppennamen qualifiziert werden.

Die Namen kollidieren ebenfalls, aber Sie können dies mithilfe eines externen Alias beheben .

Mein Rat wäre, zu vermeiden, dass in Ihre zusammengeführte Assembly öffentlich verfügbare Bibliotheken aufgenommen werden, die Ihre zusammengeführte Assembly verfügbar macht (z. B. über einen Rückgabetyp, einen Methoden- / Konstruktorparameter, ein Feld, eine Eigenschaft, ein generisches ...), es sei denn, Sie wissen genau, dass der Benutzer von Ihre zusammengeführte Assembly hängt nicht von der freistehenden Version derselben Bibliothek ab.

Steve Pick
quelle
0

Wir haben gerade angefangen, ILMerge in unseren Lösungen zu verwenden, die neu verteilt und in unseren anderen Projekten verwendet werden und bisher so gut sind. Alles scheint in Ordnung zu funktionieren. Wir haben die verpackte Baugruppe sogar direkt verschleiert.

Wir erwägen, dasselbe mit den MS Enterprise Library-Assemblys zu tun.

Das einzige wirkliche Problem, das ich dabei sehe, ist die Versionierung einzelner Assemblys aus dem Paket.

Markom
quelle
0

Ich hatte kürzlich ein Problem, bei dem ich Assembly in der Assembly zusammengefasst hatte. Ich hatte einige Klassen, die über Reflection in Umbraco Open Source CMS aufgerufen wurden.

Die Informationen zum Tätigen des Aufrufs über Reflection stammen aus einer DB-Tabelle mit dem Assembly-Namen und dem Namespace der implementierten Klasse und der Schnittstelle. Das Problem war, dass der Reflection-Aufruf fehlschlug, wenn die DLL zusammengeführt wurde. Wenn die DLL jedoch getrennt war, funktionierte alles einwandfrei. Ich denke, das Problem könnte dem ähnlich sein, das Longeasy hat.

Ismail
quelle
-2

Es scheint mir, dass die beste ILMerge-Best Practice darin besteht, ILMerge nicht zu verwenden. Verwenden Sie stattdessen SmartAssembly . Ein Grund dafür ist, dass die beste Vorgehensweise für ILMerge Nr. 2 darin besteht, PEVerify immer auszuführen, nachdem Sie ILMerge ausgeführt haben, da ILMerge nicht garantiert, dass Assemblys korrekt zu einer gültigen ausführbaren Datei zusammengeführt werden.

Weitere ILMerge-Nachteile:

  • Beim Zusammenführen werden XML-Kommentare entfernt (wenn ich mich darum kümmern würde, würde ich ein Verschleierungstool verwenden).
  • Das Erstellen einer entsprechenden PDF-Datei wird nicht korrekt verarbeitet

Ein weiteres Tool, auf das Sie achten sollten, ist Mono.Cecil und das Tool Mono.Linker [2].

[2]: http: // www.mono-project.com/Linker

user429921
quelle
"Es wird nicht korrekt mit dem Erstellen einer entsprechenden PDF-Datei umgegangen" - unter welchen Bedingungen ist dies der Fall? Ich habe gesehen, wie ILMerge zusammengeführte PDFs generiert und diese ohne Probleme verwendet hat.
Scobi
Wenn eine der Assemblys, die Sie zusammenführen möchten, noch keine PDF-Datei hat. Außerdem verarbeitet SmartAssembly WPF-Ressourcen wie BAML korrekt.
user429921
Ein großer Vorteil von ILMerge gegenüber Smartassembly besteht darin, dass XML-Dokumentationsdateien zusammengeführt werden. Smartassembly tut dies zum Zeitpunkt der Veröffentlichung nicht. - Ein bezahlter Smartassembly-Benutzer
Cameron