C# - 无法从ResourceManager获取字符串(来自附属程序集)

Arn*_* F. 4 c# resources assemblies

我正在开发一个可本地化的应用程序.在我的"本地"资源文件中,我使用默认语言(英语),如果可能的话,我加载用户的首选项和文化,并加载翻译成语言的字符串.

所以我做了什么:

private static CultureInfo _culture = CultureInfo.CurrentUICulture;
private static ResourceManager _manager;

private static void ToNeutralCulture()
{
    while (!_culture.IsNeutralCulture)
    {
        _culture = _culture.Parent;
    }
}

private static void LoadCulture()
{
    ResourceManager manager = Properties.Resources.ResourceManager;

    try
    {
        ToNeutralCulture();

        string assembly = Assembly.GetCallingAssembly().GetName().CodeBase;
        string assemblyDir = Path.GetDirectoryName(assembly);
        string assemblyName = Path.GetFileNameWithoutExtension(assembly);
        string resourceFileName = string.Format(CultureInfo.InvariantCulture,
            @"{0}\{1}_{2}.dll",
            assemblyDir,
            assemblyName,
            _culture.Name.ToUpper());

        FileInfo resourceFile = new FileInfo(resourceFileName);
        if (resourceFile.Exists)
        {
            Assembly resourceAssembly = Assembly.LoadFrom(resourceFile.FullName);
            string[] manifests = resourceAssembly.GetManifestResourceNames();

            if (manifests.Length == 1)
            {
                manager = new ResourceManager(manifests[0], resourceAssembly);
            }

            using (ResourceReader reader = new ResourceReader(resourceAssembly.GetManifestResourceStream(manifests[0])))
            {
                IDictionaryEnumerator dict = reader.GetEnumerator();
                while (dict.MoveNext())
                {
                    string key = dict.Key as string;
                    object val = dict.Value;

                    //string mVal = manager.GetString(key);
                }
            }
        }
    }
    catch (Exception ex)
    {
        Trace.WriteLine(ex.Message);

        Trace.WriteLine(string.Format(CultureInfo.InvariantCulture,
            "Fail to loading culture {0}", 
            (_culture == null) ? "--" : _culture.EnglishName));
    }

    _manager = manager;
}
Run Code Online (Sandbox Code Playgroud)

正确加载程序集,枚举器将显示资源文件中存在的所有资源,除了以下工作正常:

string mVal = manager.GetString(key);
Run Code Online (Sandbox Code Playgroud)

当我取消注释这一行时,我有一个System.Resources.MissingManifestResourceException,有人可以告诉我为什么吗?

谢谢 !


[编辑]

项目"MyApp"

namespace MyApp
{
    Assembly resourceAssembly = Assembly.LoadFrom(resourceFileName);
    string[] manifests = resourceAssembly.GetManifestResourceNames();

    if (manifests.Length == 1)
    {
        manager = new ResourceManager(manifests[0], resourceAssembly);
    }

    // Throws the exception
    manager.GetString("PleaseCallIT", null);

    // Works
    using (ResourceReader reader = new ResourceReader(resourceAssembly.GetManifestResourceStream(manifests[0])))
    {
        IDictionaryEnumerator dict = reader.GetEnumerator();
        while (dict.MoveNext())
        {
            string key = dict.key as string; // PleaseCallIT
            object val = dict.value; // Please call IT.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

项目"MyApp_FR"(Resources.Designer.cs自动生成的文件)

namespace MyApp.Properties {
    // ...
    internal static string PleaseCallIT {
        get {
            return ResourceManager.GetString("PleaseCallIT", resourceCulture);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白......

Arn*_* F. 9

我找到了原因,希望这能帮助那些处于相同情况的人.

所以,我在MyApp_FR.dll中查看了使用Resource文件生成的代码,它是:

new global::System.Resources.ResourceManager("MyApp_FR.Properties.Resources", typeof(Resources).Assembly);
Run Code Online (Sandbox Code Playgroud)

但是在检索清单文件名时,我得到了:

"MyApp_FR.Properties.Resources.resources"

似乎.resource在这个房间有很多...通过删除它,我可以正常使用我的ResourceManager,一切正常......

最终代码:

Assembly resourceAssembly = Assembly.LoadFrom(resourceFileName);
string[] manifests = resourceAssembly.GetManifestResourceNames();
if (manifests.Length == 1)
{
    string manifest = manifests[0].Replace(".resources", string.Empty);
    manager = new ResourceManager(manifest, resourceAssembly);
}

// Works !
manager.GetString("PleaseCallIT", null);
Run Code Online (Sandbox Code Playgroud)