簡體   English   中英

如何將附屬程序集嵌入到 EXE 文件中

[英]How to embed a satellite assembly into the EXE file

我遇到了一個問題,我需要將 C# 項目作為單個 EXE 文件分發,該文件不是安裝程序,而是真正的程序。 它還需要包含當前位於子目錄中的翻譯。

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

簡短的回答是肯定的,有一個名為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\\Debug\\HelloWorld.exe

是 MSDN 的示例演練,其中包含上述示例和更多內容。 你也可能想閱讀這篇博文,它進一步解釋了它的用法。

這是我在互聯網上看到的最簡單的解決方案:

這個解決方案的實現也很方便: http : //code.google.com/p/costura/wiki/HowItWorksEmbedTask

另一種選擇是將其他程序集作為 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;
    }
}

ILMerge將為您的應用程序創建一個單獨的 exe 文件。 你可以從微軟下載 它將程序集合並在一起並可以將它們內部化,以便將合並的類設置為內部。 這是我多次用來創建單個文件版本的方法。 很容易集成到您的構建過程中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM