如何将附属程序集嵌入EXE文件中

我遇到的问题是我需要将C#项目作为单个EXE文件分发,该文件不是安装程序而是真正的程序。 它还需要包含一个当前位于子目录中的转换。

是否可以将其直接嵌入二进制文件中?

这是我在互联网上看到的最简单的解决方案:

  • 如何在EXE文件中嵌入应用程序的相关DLL

也方便实施此解决方案: http : //code.google.com/p/costura/wiki/HowItWorksEmbedTask

简短的回答是肯定的,有一个名为Assembly Linker(AL.exe)的程序将以这种方式嵌入程序集。 它的主要用例是本地化,听起来就像你需要的那样。 如果是这样,它应该是直截了当的。

例如:

al / t:lib /embed:strings.de.resources / culture:de /out:MyApp.resources.dll

要么

al.exe / culture:en-US /out:bin\Debug\en-US\HelloWorld.resources.dll /embed:Resources\MyResources.en-US.resources,HelloWorld.Resources.MyResources.en-US.resources /模板:BIN \调试\ HelloWorld.exe的

这是MSDN的示例演练,其中包含上述示例等。 您也可以阅读这篇博文 ,其中详细解释了它的用法。

另一种选择是将其他程序集嵌入为EmbededResource。 然后处理app域AssemblyResolve,从这里你可以从资源中读取程序集并将其加载到运行时。 类似于以下内容:

public class HookResolver { Dictionary _loaded; public HookResolver() { _loaded = new Dictionary(StringComparer.OrdinalIgnoreCase); AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); } System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { string name = args.Name.Split(',')[0]; Assembly asm; lock (_loaded) { if (!_loaded.TryGetValue(name, out asm)) { using (Stream io = this.GetType().Assembly.GetManifestResourceStream(name)) { byte[] bytes = new BinaryReader(io).ReadBytes((int)io.Length); asm = Assembly.Load(bytes); _loaded.Add(name, asm); } } } return asm; } } 

ILMerge将为您的应用程序创建一个exe文件。 您可以从Microsoft 下载它 。 它将程序集合并在一起,并可以将它们内部化,以便将合并的类设置为internal。 这就是我用来多次创建单个文件的过程。 它很容易集成到您的构建过程中。