我遇到的问题是我需要将C#项目作为单个EXE文件分发,该文件不是安装程序而是真正的程序。它还需要包含一个当前位于子目录中的翻译。
是否可以将其直接嵌入二进制文件中?
答案 0 :(得分:10)
简短的回答是肯定的,有一个名为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 /template:bin\Debug\HelloWorld.exe
This是MSDN的示例演练,其中包含上述示例等。另外,您可能需要阅读this blog post,以便进一步解释其用法。
答案 1 :(得分:5)
这是我在互联网上看到的最简单的解决方案:
也方便实施此解决方案: http://code.google.com/p/costura/wiki/HowItWorksEmbedTask
答案 2 :(得分:3)
另一种选择是将其他程序集嵌入为EmbededResource。然后处理app域AssemblyResolve,从这里你可以从资源中读取程序集并将其加载到运行时。如下所示:
public class HookResolver
{
Dictionary<string, Assembly> _loaded;
public HookResolver()
{
_loaded = new Dictionary<string, Assembly>(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;
}
}
答案 3 :(得分:3)
ILMerge将为您的应用程序创建一个exe文件。您可以从Microsoft download it。它将程序集合并在一起并可以将它们内部化,以便将合并的类设置为internal。这就是我多次使用创建单个文件版本的方法。很容易集成到您的构建过程中。