2008-09-24 2 views

Antwort

28

Ja, Sie können das Werkzeug ILMerge verwenden.

+0

Es funktionierte für mich bisher, sogar für .NET 4.0, mit dem Hinweis auf der Projektseite gegeben. – Marcel

5

Es gibt ein Drittanbieter-Tool namens .NET Reactor, das dies für Sie tun kann. Ich habe das Tool nicht benutzt und bin mir daher nicht sicher, wie es funktioniert.

+1

Wir benutzen es, es funktioniert gut. – RickL

+0

Sie benötigen immer noch das .NET Framework. 'Nativ' beschreibt nur den Schutzansatz. –

+0

Danke für diese Info, ich habe die Antwort aktualisiert, um dies zu reflektieren. –

0

Sie müssen es nicht in mehrere Assemblys aufteilen (dies sind normalerweise Projekte in einer Visual Studio-Lösung). Das .NET Framework wird sowieso benötigt, es gibt keinen Weg - und das ist der richtige Weg - um es einzubetten.

5

Ich habe die .NETZ .NET Open Source ausführbare Packer verwendet, um EXE und DLL-Dateien in einzelne EXE-Datei zu packen. Hier ist ein Kommandozeilen-Beispiel dafür, wie DLL-Dateien in eine Datei zu packen:

netz -s application.exe foo.dll bar.dll 
+1

Hallo, ich habe netz benutzt. Aber es funktioniert nicht mit nicht verwalteten Abhängigkeiten. – mrid

+0

auch benutze ich Web-Service, den es nicht unterstützt. .NetZ ist sehr gut mit zu vielen Optionen, aber eingestellt. – Zolfaghari

8

Ja. In .NET können Sie Ihre gesamte Anwendung als einzelne EXE-Datei gekapselt haben. Stellen Sie nur sicher, dass Ihre Lösung nur ein Windows-Anwendungsprojekt enthält (und keine anderen Projekte außer Setups).

Die EXE-Datei, die von Ihrem .NET-Projekt erstellt wird, ist keine eigenständige ausführbare Datei, aber die einzige Abhängigkeit ist die .NET-Laufzeitumgebung (außer Sie Referenzen auf andere DLL-Assemblys hinzufügen). Wenn Sie .NET 2.0 verwenden (was ich empfehle), ist die Runtime auf neueren PCs vorinstalliert und lässt sich sehr einfach und schnell auf älteren Maschinen installieren (der Installer ist etwa 23 MB).

Wenn Ihre App auf andere Assemblys verweisen muss (z. B. eine Datenzugriffs-DLL oder ein .NET-Klassenbibliothek-DLL-Projekt), können Sie eines der von anderen Postern referenzierten Tools verwenden, um Ihre EXE und alle referenzierten DLLs zu kombinieren eine einzelne EXE-Datei. Jedoch würde herkömmliche Praxis diktieren einfach die EXE-Datei zusammen mit allen abhängigen DLLs als separate Dateien bereitstellen. In .NET ist die Bereitstellung abhängiger DLLs ziemlich einfach: Sie müssen sie einfach in den gleichen Ordner wie die EXE-Datei auf dem Client-Rechner kopieren, und schon sind Sie fertig.

Es empfiehlt sich, Ihre Anwendung (ob eine Datei oder viele) als Installationsprogramm für eine einzige Datei (entweder setup.EXE oder setup.MSI) bereitzustellen. .NET enthält Deployment-Projektvorlagen, die Installationsprogramme für Sie relativ einfach erstellen können.

Etwas außerhalb des Themas: Sie könnten NGEN verwenden, um Ihre .NET-Anwendung als native EXE zu kompilieren, aber es wäre immer noch abhängig von der .NET-Laufzeit. Der Vorteil der nativen Kompilierung ist, dass einige Dinge vorkompiliert werden können, aber ich habe nie eine Situation gesehen, in der diese kleine Leistungssteigerung sich lohnt.

1

Sie können versuchen, das NBox Dienstprogramm.

0

ILMerge können Baugruppen zu einer einzigen Baugruppe kombinieren sofern die Montage nur Code geschafft hat. Sie können die Befehlszeilenanwendung verwenden oder einen Verweis auf die EXE-Datei hinzufügen und sie programmgesteuert zusammenführen. Für eine GUI-Version gibt es Eazfuscator, und auch .Netz, die beide frei sind. Bezahlte Anwendungen sind BoxedApp und SmartAssembly.

Wenn Sie Assemblys mit nicht verwaltetem Code zusammenführen müssen, würde ich vorschlagen SmartAssembly. Ich hatte nie Schluckauf mit SmartAssembly, aber mit allen anderen. Hier können Sie die erforderlichen Abhängigkeiten als Ressourcen in Ihre EXE-Hauptdatei einbetten.

Sie können all dies manuell erledigen, müssen sich keine Sorgen machen, wenn eine Assembly verwaltet wird oder im gemischten Modus, indem Sie die DLL-Datei in Ihre Ressourcen einbetten und sich dann auf Assembly ResolveHandler der Assembly verlassen. Dies ist eine One-Stop-Lösung durch die Annahme des schlimmsten Falles, dh Baugruppen mit nicht verwaltetem Code.

class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
     { 
      string assemblyName = new AssemblyName(args.Name).Name; 
      if (assemblyName.EndsWith(".resources")) 
       return null; 

      string dllName = assemblyName + ".dll"; 
      string dllFullPath = Path.Combine(GetMyApplicationSpecificPath(), dllName); 

      using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName)) 
      { 
       byte[] data = new byte[stream.Length]; 
       s.Read(data, 0, data.Length); 

       // Or just byte[] data = new BinaryReader(s).ReadBytes((int)s.Length); 

       File.WriteAllBytes(dllFullPath, data); 
      } 

      return Assembly.LoadFrom(dllFullPath); 
     }; 
    } 
} 

Dabei ist Program der Klassenname. Der Schlüssel hier ist, die Bytes in eine Datei zu schreiben und von ihrem Ort zu laden. Um ein Henne-und-Ei-Problem zu vermeiden, müssen Sie sicherstellen, dass Sie den Handler deklarieren, bevor Sie auf die Assembly zugreifen und nicht auf die Assembly-Member zugreifen (oder instanziieren, was mit der Assembly zu tun hat). Teil. Stellen Sie außerdem sicher, dass GetMyApplicationSpecificPath() kein temporäres Verzeichnis ist, da temporäre Dateien versucht werden könnten, von anderen Programmen oder von Ihnen selbst gelöscht zu werden (nicht, dass es gelöscht wird, während Ihr Programm auf die DLL-Datei zugreift, aber es ist ein Ärgernis. AppData ist eine gute Lage). Beachten Sie auch, dass Sie die Bytes jedes Mal schreiben müssen; Sie können nicht von Ort laden, nur weil die DLL-Datei bereits dort ist.

Für verwaltete DLL-Dateien müssen Sie keine Bytes schreiben, sondern direkt vom Speicherort der DLL-Datei laden oder nur die Bytes lesen und die Assembly aus dem Speicher laden. So oder so:

using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName)) 
{ 
    byte[] data = new byte[stream.Length]; 
    s.Read(data, 0, data.Length); 
    return Assembly.Load(data); 
} 

// Or just 

return Assembly.LoadFrom(dllFullPath); // If location is known. 

Wenn die Assembly vollständig unmanaged ist, können Sie this link oder this als sehen, wie eine solche DLL-Dateien zu laden.

1

Ich benutze .netshrink selbst, und es tut genau das, was Sie brauchen. Es packt die Haupt- und Extra-Assemblies (DLL-Dateien) in ein ausführbares Image.

Ich benutze es schon seit einem Jahr, und ich gehe nicht zurück zu ILMerge (es stürzt immer irgendwann ab ...).

.netshrink main window from the product's page

+1

Es ist nicht kostenlos ... –

1

Jeffrey Richter schrieben in seinem book excerpt, dass eine Callback-Methode mit dem application domain’s ResolveAssembly Ereignisse registriert werden kann, die CLR zu ermöglichen Drittanbieter Baugruppen und DLL-Dateien während des Programms Initialisierung zu finden:

AppDomain.CurrentDomain.AssemblyResolve += (sender, 
    args) => { 
    String resourceName = "AssemblyLoadingAndReflection." + 
    new AssemblyName(args.Name).Name + ".dll"; 
    using (var stream =  
     Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)){ 
     Byte[] assemblyData = new Byte[stream.Length]; 
     stream.Read(assemblyData, 0, assemblyData.Length); 
     return Assembly.Load(assemblyData); 
     } 
    }; 

Disclaimer: Ich habe das selbst nicht verwendet. Soweit ich verstanden habe, muss der Client das .NET Framework installiert haben.

+0

Dies ist offenbar die Methode von Costura.Fody verwendet, die in der anderen Antwort beschrieben ist: https://StackOverflow.com/a/32556235/3195477 – DaveInCaz

8

Heute, im Jahr 2015, können Sie hierfür Costura.Fody verwenden. Wenn Sie es verwenden, wird das NuGet-Paket zu Ihrem Projekt hinzugefügt und neu kompiliert. Ich bin mir nicht sicher, ob es mit Visual   Studio   2005 wie in der Frage funktioniert, aber dann ist es auch nicht das Jahr 2008. Ich habe es in einigen meiner Projekte verwendet und es hat super funktioniert.

Fody ist ein allgemeiner Zweck Code Weaver, der frei und Open Source ist. Die Grundidee, dass der kompilierte .NET-Code nachbearbeitet werden kann, um ihn mit Funktionen zu erweitern. Beispielsweise kann die Protokollierung zu jedem Methodenaufruf usw. hinzugefügt werden. In unserem Fall werden die abhängigen DLL-Dateien in die Assemblierungsressourcen verpackt, sodass sie während der Laufzeit des Programms geladen werden können, als wären sie eigenständige Abhängigkeiten.

+2

Das ist eine richtige Antwort. Ich habe gerade mit VS 2015 und WPF App getestet. Vielen Dank! –

+2

Ich fand es ausgezeichnet für mein Projekt, das Roslyn verwendet. Installierte es über Nuget Manager und dann ... Viola! Es funktioniert einfach gut aus der Box. OP: Bitte akzeptieren Sie diese Antwort. – lwchkg

+0

Ausgezeichnete Antwort, buchstäblich nur Nuget-Paket installieren und neu erstellen. Einfach. – saarrrr

Verwandte Themen