C # - impossible d'obtenir une chaîne de caractères de ResourceManager (à partir de l'assemblage par satellite)

je développe une application localisable. Dans mon fichier de ressources "local", j'ai la langue utilisée par défaut (anglais) et si possible, je charge la préférence et la culture de l'utilisateur et je charge les chaînes traduites dans cette langue.

alors ce que j'ai fait:

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;
}

Assembly est correctement chargé et l'enquêteur va m'afficher toutes les ressources présentes dans le fichier de ressources, bien, fonctionne très bien sauf:

string mVal = manager.GetString(key);

Quand j'ai décroché cette phrase, j'ai un System.Resources.MissingManifestResourceException , quelqu'un peut-il me dire pourquoi?

Merci !


[modifier]

Projet "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.
        }
    }
}

Projet "MyApp_FR" (Resources.Designer.cs fichier généré automatiquement)

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

Je ne comprends pas...

3
demandé sur starblue 2011-03-09 16:38:31

3 réponses

j'ai trouvé pourquoi, j'espère que ça aidera quelqu'un qui est dans le même cas.

donc, j'ai regardé dans MyApp_FR.dll le code généré pour utiliser le fichier de Ressource, il est:

new global::System.Resources.ResourceManager("MyApp_FR.Properties.Resources", typeof(Resources).Assembly);

mais en récupérant les noms des fichiers de manifestes, j'ai eu:

" MyApp_FR.Propriété.Ressources.ressources "

semble être Il ya un .resource à beaucoup dans ce chambre... En l'enlevant, je peux utiliser mon gestionnaire de ressources normalement, tout fonctionne très bien...

code Final:

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);
9
répondu Arnaud F. 2011-03-09 20:12:32

De Microsoft Support:

ce problème se produit si vous utilisez une ressource localisée qui existe dans un assemblage de satellite que vous avez créé en utilisant un .ressources fichier qui a un nom de fichier inapproprié. Ce problème se produit typiquement si vous créez manuellement un assemblage satellite:

Essayez cette KB:

http://support.microsoft.com/kb/839861

2
répondu ukhardy 2011-03-09 13:43:26

une approche alternative, mis dans le suivant comme code d'essai:

string[] resources = 
    System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();

dans le débogage, vérifiez le contenu des ressources pour voir si elles correspondent à ce que vous chargez avec ResourceManager.

surtout notez, si vous obtenez quelque chose comme ' MyAssembly..Ressources.resources', vous devrez alors ajouter explicitement 'Resources' au constructeur de ResourceManager:

    private static readonly ResourceManager stringTable =
 new ResourceManager("MyAssembly.Resources", Assembly.GetExecutingAssembly());
0
répondu Jahmic 2016-06-10 11:09:29