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)
我不明白......
我找到了原因,希望这能帮助那些处于相同情况的人.
所以,我在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)