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

C# 如何将附属程序集嵌入EXE文件,c#,embed,satellite-assembly,C#,Embed,Satellite Assembly,我遇到的问题是,我需要将一个C#项目作为单个EXE文件分发,该文件不是安装程序,而是真正的程序。它还需要包含当前驻留在子目录中的翻译 是否可以将其直接嵌入二进制文件?简单的回答是可以的,有一个名为的程序将以这种方式嵌入程序集。它的主要用例是本地化,听起来这也是您需要它的原因。如果是这样的话,它应该是直截了当的 例如: al/t:lib/embed:strings.de.resources/culture:de/out:MyApp.resources.dll 或 al.exe/culture:en

我遇到的问题是,我需要将一个C#项目作为单个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


是一个it MSDN示例演练,包含上述示例和更多示例。另外,您可能还想进一步了解它的用法。

另一个选项是将其他程序集作为嵌入式资源嵌入。然后处理应用程序域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;
    }
}
公共类HookResolver
{
词典加载;
公共解析程序()
{
_loaded=新字典(StringComparer.OrdinalIgnoreCase);
AppDomain.CurrentDomain.AssemblyResolve+=新的ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
System.Reflection.Assembly CurrentDomain_AssemblyResolve(对象发送方,ResolveEventArgs args args)
{
字符串名称=args.name.Split(',')[0];
装配asm;
锁(已加载)
{
如果(!\u加载的.TryGetValue(名称,输出asm))
{
使用(Stream io=this.GetType().Assembly.GetManifestResourceStream(name))
{
byte[]bytes=新的二进制读取器(io).ReadBytes((int)io.Length);
asm=汇编.Load(字节);
_加载。添加(名称、asm);
}
}
}
返回asm;
}
}

将为应用程序创建一个exe文件。你可以从微软。它将程序集合并在一起,并可以将它们内部化,以便将合并的类设置为内部。这就是我多次用来创建单个文件版本的方法。很容易集成到构建过程中

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

此解决方案的另一个简便实现:

博客文章的链接已断开。据我所知,al.exe可用于创建附属程序集,但我认为它无法将多个区域性资源合并到一个程序集中,这正是问题所在。此链接现在已损坏。@pjc50更新了web archive的链接