如何将卫星程序集嵌入EXE文件中

18

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

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

4个回答

9
简短回答是可以的,有一个名为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 这里是一个示例步骤,其中包括上述示例和更多内容。另外,您可能想阅读这篇博客文章,其中进一步解释了其用法。

博客文章的链接已损坏。 - Kevin Kibler
3
据我所知,al.exe工具可以用来创建卫星程序集,但我认为它无法将多个区域性资源合并成一个单独的程序集,这正是问题所要求的。 - Kevin Kibler

6

1
这个链接现在已经失效了。 - pjc50
@pjc50 更新了链接,使用了网络档案馆。 - Erdogan Kurtur

5

另一种选择是将其他程序集作为EmbededResource嵌入。然后处理应用程序域的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

ILMerge将为您的应用程序创建单个exe文件。您可以从微软下载它。它将组合程序集并可以使它们内部化,以便合并的类设置为内部类。这是我多次使用的创建单文件发布的方法。它很容易集成到您的构建过程中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接