ILMerge может объединить сборки в один узел при условии, что сборка только управляемый код. Вы можете использовать приложение командной строки или добавить ссылку на exe и программно объединить. Для версии GUI есть Eazfuscator, а также .Netz, оба из которых являются бесплатными. Платные приложения включают BoxedApp и SmartAssembly.
Если вам нужно объединить сборки с неуправляемым кодом, я бы предложил SmartAssembly. У меня никогда не было икоты с SmartAssembly, но со всеми остальными. Здесь он может встраивать необходимые зависимости в качестве ресурсов в ваш основной exe.
Вы можете сделать все это вручную, не беспокоясь, если сборка управляется или в смешанном режиме, вставив dll в ваши ресурсы, а затем опираясь на сборку AppDomain ResolveHandler
. Это одностановленное решение, приняв наихудший случай, то есть сборки с неуправляемым кодом.
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);
};
}
Ключ здесь состоит в том, чтобы написать байты в файл и загрузить из его местоположения. Чтобы избежать проблемы с курицей и яйцом, вы должны убедиться, что вы объявляете обработчик перед доступом к сборке и что вы не получаете доступа к членам сборки (или создаете экземпляр всего, что связано с сборкой) внутри части загрузки (сборки). Также следите за тем, чтобы GetMyApplicationSpecificPath()
не был временным каталогом, так как файлы temp можно было бы стереть другими программами или самим собой (не то, что он будет удален, пока ваша программа обратится к DLL, но, по крайней мере, это неприятность. хорошее место). Также обратите внимание, что вы должны каждый раз писать байты, вы не можете загружать из местоположения только «потому что dll уже там находится.
Для управляемых DLL вам не нужно писать байты, а загружать непосредственно из места расположения dll или просто читать байты и загружать сборку из памяти. Как это или так:
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.
Если сборка полностью неуправляемая, вы можете увидеть это link или this о том, как загрузить такие библиотеки DLL.
Возможно, но вы получите большой исполняемый файл (Base64 будет использоваться для кодирования вашей DLL). – 2010-10-28 13:56:18