ILMerge może łączyć zespoły w jeden pojedynczy zespół, pod warunkiem, że zespół ma tylko zarządzany kod. Możesz użyć aplikacji wiersza polecenia lub dodać odwołanie do pliku exe i scalić programowo. W przypadku wersji GUI dostępny jest Eazfuscator , a także .Netz, które są bezpłatne. Płatne aplikacje to BoxedApp i SmartAssembly .
Jeśli musisz scalić zestawy z niezarządzanym kodem, sugerowałbym SmartAssembly . Nigdy nie miałem czkawki z SmartAssembly, ale ze wszystkimi innymi. Tutaj może osadzić wymagane zależności jako zasoby w głównym pliku exe.
Możesz zrobić to wszystko ręcznie, nie martwiąc się, czy asemblerem zarządzany jest tryb mieszany, osadzając dll w swoich zasobach, a następnie polegając na asemblerze AppDomain ResolveHandler
. Jest to kompleksowe rozwiązanie, przyjmując najgorszy przypadek, tj. Zespoły z niezarządzanym kodem.
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);
};
}
Kluczem tutaj jest zapis bajtów do pliku i ładowanie z jego lokalizacji. Aby uniknąć problemu z kurczakiem i jajkiem, musisz upewnić się, że deklarujesz moduł obsługi przed uzyskaniem dostępu do zespołu i że nie masz dostępu do elementów zestawu (lub tworzenia instancji wszystkiego, co ma do czynienia z zespołem) wewnątrz części ładowania (rozwiązywania zespołu). Upewnij się również, GetMyApplicationSpecificPath()
czy nie ma katalogu tymczasowego, ponieważ pliki tymczasowe mogłyby zostać usunięte przez inne programy lub przez ciebie (nie dlatego, że zostaną usunięte, gdy twój program uzyskuje dostęp do biblioteki dll, ale przynajmniej jest to uciążliwe. AppData jest dobra Lokalizacja). Zauważ też, że musisz pisać bajty za każdym razem, nie możesz załadować z lokalizacji, ponieważ biblioteka DLL już tam znajduje się.
W przypadku bibliotek DLL zarządzanych nie trzeba pisać bajtów, ale ładować bezpośrednio z lokalizacji biblioteki DLL lub po prostu czytać bajty i ładować zestaw z pamięci. Tak lub mniej:
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.
Jeśli zestaw jest całkowicie niezarządzany, możesz zobaczyć ten link lub ten sposób ładowania takich bibliotek dll.