【问题标题】:Embedding Localization Resources .DLL's to the Executable in C#?将本地化资源 .DLL 嵌入到 C# 中的可执行文件中?
【发布时间】:2011-11-21 06:45:05
【问题描述】:

我想让我的程序多语言。我已经通过 Form 的 Localizable 和 Language 属性成功地使程序多语言。它制作了一些 .resx 文件。然后我从 .resx 文件中删除了不需要的文件,例如图像(它们在所有语言中都是相同的)等。

问题是,例如,它还生成了一个名为“en”的文件夹,而在该文件夹中,另一个生成的文件名为“ProjectName.resources.dll”。

有没有办法将此资源文件嵌入到 .exe 中?将其添加到资源并将构建操作设置为“嵌入式资源”也不起作用。

谢谢。

【问题讨论】:

  • 在发布之前我已经尝试过 ILMerge。尝试了汇编链接器,但无法使其工作。 csc.exe 由于引用而给出了一些错误,并且似乎程序集链接器导致可执行文件不使用资源 dll。
  • 我不明白为什么 MS 强制重新发明轮子...
  • 卫星程序集必须存储在具有区域性名称的子目录中。每个 DLL 都包含为该区域性本地化的资源。这是设计使然,试图改变它会破坏本地化。
  • 奇怪的是,您可以嵌入并合并诸如 3rd 方依赖项/引用之类的所有内容,但您不能嵌入附属程序集 :( 看来,我需要构建自己的语言更改方法。 ..

标签: c# .net dll localization embedding


【解决方案1】:

在 .NET Framework 4 中,您可以将资源库嵌入到可执行文件中。

http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve.aspx

只需创建相同的结构(使用本地化文件夹 'lib/en'、'lib/de' )并嵌入它们。

private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) {
    AssemblyName MissingAssembly = new AssemblyName(args.Name);
    CultureInfo ci = MissingAssembly.CultureInfo;

    ...
    resourceName = "MyApp.lib." + ci.Name.Replace("-","_") + "." + MissingAssembly.Name + ".dll";
    var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)
    ...
}

【讨论】:

  • 当我使用 dll 资源添加本地化文件夹时,我收到错误“资源名称“MyApp.MyApp.resources.dll”不能多次使用。如果我现在排除我的 resx 文件从项目中,我不再收到此错误,但我现在收到另一个错误:“TranslatedStrings 不是资源的成员”。我的 resx 文件称为“TranslatedStrings.resx”、“TranslatedStrings.it.resx”等。跨度>
【解决方案2】:

您前段时间问过这个问题并且您已经接受了答案,但我仍然会尝试提供另一种方法。我遇到了同样的问题,我就是这样解决的:

我将 dll 作为资源添加到我的 C#-Project 中,并将此代码添加到我的 Main-Method(启动主 winform 的那个)中。

public static void Main(string[] args)
{
    if (InitdeDEDll()) // Create dll if it's missing.
    {
        // Restart the application if the language-package was added
        Application.Restart();
        return;
    }
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new YOURMAINFORM());
}

private static bool InitdeDEDll() // Initialize the German de-DE DLL
{
    try
    {
        // Language of my package. This will be the name of the subfolder.
        string language = "de-DE";
        return TryCreateFileFromRessource(language, @"NAMEOFYOURDLL.dll",
            NAMESPACEOFYOURRESSOURCE.NAMEOFYOURDLLINRESSOURCEFILE);
    }
    catch (Exception)
    {
        return false;
    }
}

private static bool TryCreateFileFromRessource(string subfolder, string fileName, byte[] buffer)
{
    try
    {
        // path of the subfolder
        string subfolderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + (subfolder != "" ? @"\" : "") + subfolder;

        // Create subfolder if it doesn't exist
        if (!Directory.Exists(subfolder))
            Directory.CreateDirectory(subfolderPath);


        fileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" + subfolder + (subfolder!=""?@"\":"") + fileName;
        if (!File.Exists(fileName)) // if the dll doesn't already exist, it has to be created
        {
            // Write dll
            Stream stream = File.Create(fileName);
            stream.Write(buffer, 0, buffer.GetLength(0));
            stream.Close();
        }
        else
        {
            return false;
        }
    }
    catch
    {
        return false;
    }

    return true;
}

}

注意:如果文件夹和语言 dll 丢失,这将再次创建它,因此您不必再关心复制该文件夹和 dll 与您的 exe 文件。如果您希望它完全消失,这当然不是正确的方法。

【讨论】:

    猜你喜欢
    • 2016-10-22
    • 2023-04-06
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 2011-05-08
    • 1970-01-01
    相关资源
    最近更新 更多