Classe System.Resources.ResourceManager

Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.

Importante

La chiamata a metodi da questa classe con dati non attendibili costituisce un rischio per la sicurezza. Chiamare i metodi da questa classe solo con dati attendibili. Per altre informazioni, vedere Convalidare tutti gli input.

La ResourceManager classe recupera le risorse da un file binario con estensione resources incorporato in un assembly o da un file con estensione resources autonomo. Se un'app è stata localizzata e le risorse localizzate sono state distribuite negli assembly satellite, cerca risorse specifiche delle impostazioni cultura, fornisce il fallback delle risorse quando una risorsa localizzata non esiste e supporta la serializzazione delle risorse.

App desktop

Per le app desktop, la ResourceManager classe recupera le risorse dai file di risorse binarie (con estensione resources). In genere, un compilatore di linguaggio o il linker assembly (AL.exe) incorpora questi file di risorse in un assembly. È anche possibile usare un ResourceManager oggetto per recuperare le risorse direttamente da un file con estensione resources non incorporato in un assembly chiamando il CreateFileBasedResourceManager metodo .

Attenzione

L'uso di file con estensione resources autonomi in un'app ASP.NET interromperà la distribuzione di XCOPY, perché le risorse rimangono bloccate fino a quando non vengono rilasciate in modo esplicito dal ReleaseAllResources metodo . Se si vogliono distribuire risorse con le app ASP.NET, è necessario compilare i file con estensione resources in assembly satellite.

In un'app basata su risorse, un file con estensione resources contiene le risorse delle impostazioni cultura predefinite le cui risorse vengono usate se non è possibile trovare risorse specifiche delle impostazioni cultura. Ad esempio, se le impostazioni cultura predefinite di un'app sono inglese (en), le risorse in lingua inglese vengono usate ogni volta che non è possibile trovare risorse localizzate per impostazioni cultura specifiche, ad esempio inglese (Stati Uniti) (en-US) o francese (Francia) (fr-FR). In genere, le risorse per le impostazioni cultura predefinite sono incorporate nell'assembly principale dell'app e le risorse per altre impostazioni cultura localizzate vengono incorporate negli assembly satellite. Gli assembly satellite contengono solo risorse. Hanno lo stesso nome di file radice dell'assembly principale e un'estensione di .resources.dll. Per le app i cui assembly non sono registrati nella Global Assembly Cache, gli assembly satellite vengono archiviati in una sottodirectory dell'app il cui nome corrisponde alle impostazioni cultura dell'assembly.

Creare le risorse

Quando si sviluppa un'app basata su risorse, si archiviano informazioni sulle risorse in file di testo (file con estensione .txt o restext) o file XML (file con estensione resx). Compilare quindi i file di testo o XML con il generatore di file di risorse (Resgen.exe) per creare un file binario con estensione resources. È quindi possibile incorporare il file con estensione resources risultante in un eseguibile o in una libreria usando un'opzione del compilatore, /resources ad esempio per i compilatori C# e Visual Basic, oppure è possibile incorporarlo in un assembly satellite usando Assembly Linker (AI.exe). Se si include un file resx nel progetto di Visual Studio, Visual Studio gestisce automaticamente la compilazione e l'incorporamento delle risorse predefinite e localizzate come parte del processo di compilazione.

Idealmente, devi creare risorse per ogni lingua supportata dall'app o almeno per un sottoinsieme significativo di ogni lingua. I nomi di file binari con estensione resources seguono il nome base della convenzione di denominazione.cultureName.resources, dove basename è il nome dell'app o il nome di una classe, a seconda del livello di dettaglio desiderato. La CultureInfo.Name proprietà viene utilizzata per determinare cultureName. Una risorsa per le impostazioni cultura predefinite dell'app deve essere denominata basename.resources.

Si supponga, ad esempio, che un assembly disponga di diverse risorse in un file di risorse con il nome di base MyResources. Questi file di risorse devono avere nomi come MyResources.ja-JP.resources per le impostazioni cultura giapponesi (giapponesi), MyResources.de.resources per le impostazioni cultura tedesche, MyResources.zh-CHS.resources per le impostazioni cultura cinesi semplificate e MyResources.fr-BE.resources per le impostazioni cultura francesi (Belgio). Il file di risorse predefinito deve essere denominato MyResources.resources. I file di risorse specifici delle impostazioni cultura vengono comunemente inseriti in assembly satellite per ogni impostazione cultura. Il file di risorse predefinito deve essere incorporato nell'assembly principale dell'app.

Si noti che Assembly Linker consente di contrassegnare le risorse come private, ma è sempre necessario contrassegnarle come pubbliche in modo che possano essere accessibili da altri assembly. Poiché un assembly satellite non contiene codice, le risorse contrassegnate come private non sono disponibili per l'app tramite qualsiasi meccanismo.

Per altre informazioni sulla creazione, la creazione di pacchetti e la distribuzione di risorse, vedere gli articoli Creazione di file di risorse, creazione di assembly satellite e creazione di pacchetti e distribuzione di risorse.

Creare un'istanza di un oggetto ResourceManager

Si crea un'istanza di un ResourceManager oggetto che recupera le risorse da un file con estensione resources incorporato chiamando uno degli overload del costruttore di classe. In questo modo un ResourceManager oggetto viene associato a un particolare file con estensione resources e a qualsiasi file con estensione resources localizzato associato negli assembly satellite.

I due costruttori più comunemente chiamati sono:

  • ResourceManager(String, Assembly) cerca le risorse in base a due informazioni fornite: il nome di base del file resources e l'assembly in cui risiede il file con estensione resources predefinito. Il nome di base include lo spazio dei nomi e il nome radice del file con estensione resources, senza le impostazioni cultura o l'estensione. Si noti che i file con estensione resources compilati dalla riga di comando in genere non includono un nome dello spazio dei nomi, mentre i file con estensione resources creati nell'ambiente di Visual Studio. Ad esempio, se un file di risorse è denominato MyCompany.StringResources.resources e il ResourceManager costruttore viene chiamato da un metodo statico denominato Example.Main, il codice seguente crea un'istanza di un ResourceManager oggetto in grado di recuperare le risorse dal file resources:

    ResourceManager rm = new ResourceManager("MyCompany.StringResources",
                                             typeof(Example).Assembly);
    
    Dim rm As New ResourceManager("MyCompany.StringResources",
                                GetType(Example2).Assembly)
    
  • ResourceManager(Type) cerca le risorse negli assembly satellite in base alle informazioni di un oggetto di tipo. Il nome completo del tipo corrisponde al nome di base del file con estensione resources senza l'estensione del nome file. Nelle app desktop create tramite Progettazione risorse di Visual Studio, Visual Studio crea una classe wrapper il cui nome completo corrisponde al nome radice del file con estensione resources. Ad esempio, se un file di risorse è denominato MyCompany.StringResources.resources e esiste una classe wrapper denominata MyCompany.StringResources, il codice seguente crea un'istanza di un ResourceManager oggetto in grado di recuperare le risorse dal file resources:

    ResourceManager rm = new ResourceManager(typeof(MyCompany.StringResources));
    
    Dim rm As New ResourceManager(GetType(MyCompany.StringResources))
    

Se non è possibile trovare le risorse appropriate, la chiamata al costruttore crea un oggetto valido ResourceManager . Tuttavia, il tentativo di recuperare una risorsa genera un'eccezione MissingManifestResourceException . Per informazioni sulla gestione dell'eccezione, vedere la sezione Handle MissingManifestResourceException e MissingSatelliteAssemblyException Exceptions più avanti in questo articolo.

Nell'esempio seguente viene illustrato come creare un'istanza di un ResourceManager oggetto . Contiene il codice sorgente per un eseguibile denominato ShowTime.exe. Include anche il file di testo seguente denominato Strings.txt che contiene una singola risorsa stringa, TimeHeader:

TimeHeader=The current time is

È possibile usare un file batch per generare il file di risorse e incorporarlo nel file eseguibile. Ecco il file batch per generare un eseguibile usando il compilatore C#:

resgen strings.txt
csc ShowTime.cs /resource:strings.resources

Per il compilatore Visual Basic, è possibile usare il file batch seguente:

resgen strings.txt
vbc ShowTime.vb /resource:strings.resources
using System;
using System.Resources;

public class ShowTimeEx
{
    public static void Main()
    {
        ResourceManager rm = new ResourceManager("Strings",
                                 typeof(Example).Assembly);
        string timeString = rm.GetString("TimeHeader");
        Console.WriteLine("{0} {1:T}", timeString, DateTime.Now);
    }
}
// The example displays output like the following:
//        The current time is 2:03:14 PM
Imports System.Resources

Module Example6
    Public Sub Main()
        Dim rm As New ResourceManager("Strings", GetType(Example6).Assembly)
        Dim timeString As String = rm.GetString("TimeHeader")
        Console.WriteLine("{0} {1:T}", timeString, Date.Now)
    End Sub
End Module
' The example displays output similar to the following:
'       The current time is 2:03:14 PM

ResourceManager e risorse specifiche delle impostazioni cultura

Un'app localizzata richiede la distribuzione di risorse, come descritto nell'articolo Creazione di pacchetti e distribuzione di risorse. Se gli assembly sono configurati correttamente, gestione risorse determina le risorse da recuperare in base alla proprietà del Thread.CurrentUICulture thread corrente. Questa proprietà restituisce anche le impostazioni cultura dell'interfaccia utente del thread corrente. Ad esempio, se un'app viene compilata con risorse predefinite in lingua inglese nell'assembly principale e con risorse in lingua francese e russa in due assembly satellite e la Thread.CurrentUICulture proprietà è impostata su fr-FR, il gestore risorse recupera le risorse francesi.

È possibile impostare la CurrentUICulture proprietà in modo esplicito o implicito. La modalità di impostazione determina il modo in cui l'oggetto ResourceManager recupera le risorse in base alle impostazioni cultura:

  • Se si imposta in modo esplicito la Thread.CurrentUICulture proprietà su impostazioni cultura specifiche, gestione risorse recupera sempre le risorse per tali impostazioni cultura, indipendentemente dal browser o dalla lingua del sistema operativo dell'utente. Si consideri un'app compilata con le risorse predefinite in lingua inglese e tre assembly satellite contenenti risorse per l'inglese (Stati Uniti), il francese (Francia) e il russo (Russia). Se la CurrentUICulture proprietà è impostata su fr-FR, l'oggetto ResourceManager recupera sempre le risorse francese (Francia), anche se la lingua del sistema operativo dell'utente non è francese. Assicurarsi che questo sia il comportamento desiderato prima di impostare la proprietà in modo esplicito.

    Nelle app di ASP.NET è necessario impostare la Thread.CurrentUICulture proprietà in modo esplicito, perché è improbabile che l'impostazione nel server corrisponda alle richieste client in ingresso. Un'app ASP.NET può impostare la Thread.CurrentUICulture proprietà in modo esplicito sulla lingua di accettazione del browser dell'utente.

    L'impostazione esplicita della Thread.CurrentUICulture proprietà definisce le impostazioni cultura dell'interfaccia utente correnti per il thread. Non influisce sulle impostazioni cultura correnti dell'interfaccia utente di altri thread in un'app.

  • È possibile impostare le impostazioni cultura dell'interfaccia utente di tutti i thread in un dominio dell'app assegnando un CultureInfo oggetto che rappresenta tali impostazioni cultura alla proprietà statica CultureInfo.DefaultThreadCurrentUICulture .

  • Se non imposti in modo esplicito le impostazioni cultura correnti dell'interfaccia utente e non definisci impostazioni cultura predefinite per il dominio dell'app corrente, la CultureInfo.CurrentUICulture proprietà viene impostata in modo implicito dalla funzione windows GetUserDefaultUILanguage . Questa funzione viene fornita dalla interfaccia utente multilingue (MUI), che consente all'utente di impostare la lingua predefinita. Se la lingua dell'interfaccia utente non è impostata dall'utente, per impostazione predefinita viene impostata la lingua installata dal sistema, ovvero la lingua delle risorse del sistema operativo.

L'esempio semplice "Hello world" seguente imposta in modo esplicito le impostazioni cultura dell'interfaccia utente correnti. Contiene risorse per tre impostazioni cultura: inglese (Stati Uniti) o en-US, francese (Francia) o fr-FR e russo (Russia) o ru-UR. Le risorse en-US sono contenute in un file di testo denominato Greetings.txt:

HelloString=Hello world!

Le risorse fr-FR sono contenute in un file di testo denominato Greetings.fr-FR.txt:

HelloString=Salut tout le monde!

Le risorse ru-UR sono contenute in un file di testo denominato Greetings.ru-RU.txt:

HelloString=Всем привет!

Ecco il codice sorgente per l'esempio (Example.vb per la versione di Visual Basic o Example.cs per la versione C#):

using System;
using System.Globalization;
using System.Resources;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // Create array of supported cultures
        string[] cultures = { "en-CA", "en-US", "fr-FR", "ru-RU" };
        Random rnd = new Random();
        int cultureNdx = rnd.Next(0, cultures.Length);
        CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
        ResourceManager rm = new ResourceManager("Greetings", typeof(Example).Assembly);
        try
        {
            CultureInfo newCulture = new CultureInfo(cultures[cultureNdx]);
            Thread.CurrentThread.CurrentCulture = newCulture;
            Thread.CurrentThread.CurrentUICulture = newCulture;
            string greeting = String.Format("The current culture is {0}.\n{1}",
                                            Thread.CurrentThread.CurrentUICulture.Name,
                                            rm.GetString("HelloString"));
            Console.WriteLine(greeting);
        }
        catch (CultureNotFoundException e)
        {
            Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName);
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = originalCulture;
            Thread.CurrentThread.CurrentUICulture = originalCulture;
        }
    }
}
// The example displays output like the following:
//       The current culture is ru-RU.
//       Всем привет!
Imports System.Globalization
Imports System.Resources
Imports System.Threading

Module Example
   Sub Main()
      ' Create array of supported cultures
      Dim cultures() As String = {"en-CA", "en-US", "fr-FR", "ru-RU" }
      Dim rnd As New Random()
      Dim cultureNdx As Integer = rnd.Next(0, cultures.Length)
      Dim originalCulture As CultureInfo = Thread.CurrentThread.CurrentCulture
      Dim rm As New ResourceManager("Greetings", GetType(Example).Assembly)
      Try
         Dim newCulture As New CultureInfo(cultures(cultureNdx))
         Thread.CurrentThread.CurrentCulture = newCulture
         Thread.CurrentThread.CurrentUICulture = newCulture
         Dim greeting As String = String.Format("The current culture is {0}.{1}{2}",
                                                Thread.CurrentThread.CurrentUICulture.Name,
                                                vbCrLf, rm.GetString("HelloString"))

         Console.WriteLine(greeting)
      Catch e As CultureNotFoundException
         Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName)
      Finally
         Thread.CurrentThread.CurrentCulture = originalCulture
         Thread.CurrentThread.CurrentUICulture = originalCulture
      End Try
   End Sub
End Module
' The example displays output like the following:
'       The current culture is ru-RU.
'       Всем привет!

Per compilare questo esempio, creare un file batch (.bat) contenente i comandi seguenti ed eseguirlo dal prompt dei comandi. Se si usa C#, specificare csc anziché vbc e Example.cs anziché Example.vb.

resgen Greetings.txt
vbc Example.vb /resource:Greetings.resources

resgen Greetings.fr-FR.txt
Md fr-FR
al /embed:Greetings.fr-FR.resources /culture:fr-FR /out:fr-FR\Example.resources.dll

resgen Greetings.ru-RU.txt
Md ru-RU
al /embed:Greetings.ru-RU.resources /culture:ru-RU /out:ru-RU\Example.resources.dll

Recuperare le risorse

I metodi e GetString(String) vengono chiamati GetObject(String) per accedere a una risorsa specifica. È anche possibile chiamare il GetStream(String) metodo per recuperare le risorse non stringa come matrice di byte. Per impostazione predefinita, in un'app con risorse localizzate, questi metodi restituiscono la risorsa per le impostazioni cultura determinate dalle impostazioni cultura correnti dell'interfaccia utente del thread che ha effettuato la chiamata. Per altre informazioni sulla definizione delle impostazioni cultura correnti di un thread, vedere la sezione precedente ResourceManager e le risorse specifiche delle impostazioni cultura. Se resource manager non riesce a trovare la risorsa per le impostazioni cultura dell'interfaccia utente del thread corrente, usa un processo di fallback per recuperare la risorsa specificata. Se resource manager non riesce a trovare risorse localizzate, usa le risorse delle impostazioni cultura predefinite. Per altre informazioni sulle regole di fallback delle risorse, vedere la sezione "Processo di fallback delle risorse" dell'articolo Creazione di pacchetti e distribuzione di risorse.

Nota

Se non è possibile trovare il file con estensione resources specificato nel costruttore della ResourceManager classe, il tentativo di recuperare una risorsa genera un'eccezione MissingManifestResourceException o MissingSatelliteAssemblyException . Per informazioni sulla gestione dell'eccezione, vedere la sezione Handle MissingManifestResourceException e MissingSatelliteAssemblyException Exceptions più avanti in questo articolo.

Nell'esempio seguente viene usato il GetString metodo per recuperare risorse specifiche delle impostazioni cultura. È costituito da risorse compilate da .txt file per le impostazioni cultura inglese (en), francese (Francia) (fr-FR) e russo (Russia) (ru-UR). L'esempio modifica le impostazioni cultura correnti e le impostazioni cultura correnti dell'interfaccia utente in Inglese (Stati Uniti), Francese (Francia), Russo (Russia) e Svedese (Svezia). Chiama quindi il GetString metodo per recuperare la stringa localizzata, visualizzata insieme al giorno e al mese correnti. Si noti che l'output visualizza la stringa localizzata appropriata tranne quando le impostazioni cultura dell'interfaccia utente correnti sono svedesi (Svezia). Poiché le risorse in lingua svedese non sono disponibili, l'app usa invece le risorse delle impostazioni cultura predefinite, ovvero inglese.

L'esempio richiede i file di risorse basati sul testo elencati nella tabella seguente. Ogni oggetto ha una singola risorsa stringa denominata DateStart.

Cultura File name Nome risorsa Valore della risorsa
en-US DateStrings.txt DateStart Oggi è
fr-FR DateStrings.fr-FR.txt DateStart Aujourd'hui, c'est le
ru-RU DateStrings.ru-RU.txt DateStart Сегодня

Ecco il codice sorgente per l'esempio (ShowDate.vb per la versione di Visual Basic o ShowDate.cs per la versione C# del codice).

using System;
using System.Globalization;
using System.Resources;
using System.Threading;

[assembly: NeutralResourcesLanguage("en")]

public class ShowDateEx
{
    public static void Main()
    {
        string[] cultureNames = { "en-US", "fr-FR", "ru-RU", "sv-SE" };
        ResourceManager rm = new ResourceManager("DateStrings",
                                                 typeof(Example).Assembly);

        foreach (var cultureName in cultureNames)
        {
            CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;

            Console.WriteLine("Current UI Culture: {0}",
                              CultureInfo.CurrentUICulture.Name);
            string dateString = rm.GetString("DateStart");
            Console.WriteLine("{0} {1:M}.\n", dateString, DateTime.Now);
        }
    }
}
// The example displays output similar to the following:
//       Current UI Culture: en-US
//       Today is February 03.
//       
//       Current UI Culture: fr-FR
//       Aujourd'hui, c'est le 3 février
//       
//       Current UI Culture: ru-RU
//       Сегодня февраля 03.
//       
//       Current UI Culture: sv-SE
//       Today is den 3 februari.
Imports System.Globalization
Imports System.Resources
Imports System.Threading

<Assembly:NeutralResourcesLanguage("en")>

Module Example5
    Public Sub Main()
        Dim cultureNames() As String = {"en-US", "fr-FR", "ru-RU", "sv-SE"}
        Dim rm As New ResourceManager("DateStrings",
                                    GetType(Example5).Assembly)

        For Each cultureName In cultureNames
            Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture(cultureName)
            Thread.CurrentThread.CurrentCulture = culture
            Thread.CurrentThread.CurrentUICulture = culture

            Console.WriteLine("Current UI Culture: {0}",
                           CultureInfo.CurrentUICulture.Name)
            Dim dateString As String = rm.GetString("DateStart")
            Console.WriteLine("{0} {1:M}.", dateString, Date.Now)
            Console.WriteLine()
        Next
    End Sub
End Module
' The example displays output similar to the following:
'       Current UI Culture: en-US
'       Today is February 03.
'       
'       Current UI Culture: fr-FR
'       Aujourd'hui, c'est le 3 février
'       
'       Current UI Culture: ru-RU
'       Сегодня февраля 03.
'       
'       Current UI Culture: sv-SE
'       Today is den 3 februari.

Per compilare questo esempio, creare un file batch contenente i comandi seguenti ed eseguirlo dal prompt dei comandi. Se si usa C#, specificare csc anziché vbc e showdate.cs anziché showdate.vb.

resgen DateStrings.txt
vbc showdate.vb /resource:DateStrings.resources

md fr-FR
resgen DateStrings.fr-FR.txt
al /out:fr-FR\Showdate.resources.dll /culture:fr-FR /embed:DateStrings.fr-FR.resources

md ru-RU
resgen DateStrings.ru-RU.txt
al /out:ru-RU\Showdate.resources.dll /culture:ru-RU /embed:DateStrings.ru-RU.resources

Esistono due modi per recuperare le risorse di impostazioni cultura specifiche diverse dalle impostazioni cultura correnti dell'interfaccia utente:

  • È possibile chiamare il GetString(String, CultureInfo)metodo , GetObject(String, CultureInfo)o GetStream(String, CultureInfo) per recuperare una risorsa per impostazioni cultura specifiche. Se non è possibile trovare una risorsa localizzata, gestione risorse usa il processo di fallback delle risorse per individuare una risorsa appropriata.
  • È possibile chiamare il GetResourceSet metodo per ottenere un ResourceSet oggetto che rappresenta le risorse per impostazioni cultura specifiche. Nella chiamata al metodo è possibile determinare se il gestore risorse esegue il probe per le impostazioni cultura padre se non è in grado di trovare risorse localizzate o se esegue semplicemente il fallback alle risorse delle impostazioni cultura predefinite. È quindi possibile usare i ResourceSet metodi per accedere alle risorse (localizzate per tali impostazioni cultura) in base al nome o per enumerare le risorse nel set.

Gestire le eccezioni MissingManifestResourceException e MissingSatelliteAssemblyException

Se si tenta di recuperare una risorsa specifica, ma resource manager non riesce a trovare tale risorsa e non sono state definite impostazioni cultura predefinite oppure non è possibile trovare le risorse delle impostazioni cultura predefinite, gestione risorse genera un'eccezione MissingManifestResourceException se si prevede di trovare le risorse nell'assembly principale o se MissingSatelliteAssemblyException si prevede di trovare le risorse in un assembly satellite. Si noti che l'eccezione viene generata quando si chiama un metodo di recupero delle risorse, GetString ad esempio o GetObjecte non quando si crea un'istanza di un ResourceManager oggetto .

L'eccezione viene in genere generata nelle condizioni seguenti:

  • Il file di risorse o l'assembly satellite appropriato non esiste. Se resource manager prevede che le risorse predefinite dell'app siano incorporate nell'assembly principale dell'app, sono assenti. Se l'attributo NeutralResourcesLanguageAttribute indica che le risorse predefinite dell'app risiedono in un assembly satellite, tale assembly non può essere trovato. Quando si compila l'app, assicurarsi che le risorse siano incorporate nell'assembly principale o che l'assembly satellite necessario venga generato e denominato in modo appropriato. Il nome deve avere il formato appName.resources.dll e deve trovarsi in una directory denominata in base alle impostazioni cultura di cui contiene le risorse.

  • L'app non ha impostazioni cultura predefinite o neutre definite. Aggiungere l'attributo NeutralResourcesLanguageAttribute a un file di codice sorgente o al file di informazioni sul progetto (AssemblyInfo.vb per un'app Visual Basic o AssemblyInfo.cs per un file di app C#).

  • Il baseName parametro nel ResourceManager(String, Assembly) costruttore non specifica il nome di un file con estensione resources. Il nome deve includere lo spazio dei nomi completo del file di risorse, ma non l'estensione del nome file. In genere, i file di risorse creati in Visual Studio includono nomi degli spazi dei nomi, ma i file di risorse creati e compilati al prompt dei comandi non lo fanno. È possibile determinare i nomi dei file con estensione resources incorporati compilando ed eseguendo l'utilità seguente. Si tratta di un'app console che accetta il nome di un assembly principale o di un assembly satellite come parametro della riga di comando. Vengono visualizzate le stringhe che devono essere specificate come baseName parametro in modo che resource manager possa identificare correttamente la risorsa.

    using System;
    using System.IO;
    using System.Reflection;
    
    public class Example0
    {
       public static void Main()
       {
          if (Environment.GetCommandLineArgs().Length == 1) { 
             Console.WriteLine("No filename.");
             return;
          }
          
          string filename = Environment.GetCommandLineArgs()[1].Trim();
          // Check whether the file exists.
          if (! File.Exists(filename)) {
             Console.WriteLine("{0} does not exist.", filename);
             return;
          }   
          
          // Try to load the assembly.
          Assembly assem = Assembly.LoadFrom(filename);
          Console.WriteLine("File: {0}", filename);
             
          // Enumerate the resource files.
          string[] resNames = assem.GetManifestResourceNames();
          if (resNames.Length == 0)
             Console.WriteLine("   No resources found.");
    
          foreach (var resName in resNames)
             Console.WriteLine("   Resource: {0}", resName.Replace(".resources", ""));
    
          Console.WriteLine();
       }
    }
    
    Imports System.IO
    Imports System.Reflection
    Imports System.Resources
    
    Module Example
       Public Sub Main()
          If Environment.GetCommandLineArgs.Length = 1 Then 
             Console.WriteLine("No filename.")
             Exit Sub
          End If
          Dim filename As String = Environment.GetCommandLineArgs(1).Trim()
          ' Check whether the file exists.
          If Not File.Exists(filename) Then
             Console.WriteLine("{0} does not exist.", filename)
             Exit Sub
          End If   
          
          ' Try to load the assembly.
          Dim assem As Assembly = Assembly.LoadFrom(filename)
          Console.WriteLine("File: {0}", filename)
             
          ' Enumerate the resource files.
          Dim resNames() As String = assem.GetManifestResourceNames()
          If resNames.Length = 0 Then
             Console.WriteLine("   No resources found.")
          End If
          For Each resName In resNames
             Console.WriteLine("   Resource: {0}", resName.Replace(".resources", ""))
          Next
          Console.WriteLine()
       End Sub
    End Module
    

Se si modificano le impostazioni cultura correnti dell'applicazione in modo esplicito, è necessario ricordare anche che gestione risorse recupera un set di risorse in base al valore della CultureInfo.CurrentUICulture proprietà e non alla CultureInfo.CurrentCulture proprietà . In genere, se si modifica un valore, è necessario modificare anche l'altro.

Controllo delle versioni delle risorse

Poiché l'assembly principale che contiene le risorse predefinite di un'app è separato dagli assembly satellite dell'app, è possibile rilasciare una nuova versione dell'assembly principale senza ridistribuire gli assembly satellite. Usare l'attributo SatelliteContractVersionAttribute per usare assembly satellite esistenti e indicare al gestore risorse di non ridistribuirli con una nuova versione dell'assembly principale.

Per altre informazioni sul supporto del controllo delle versioni per gli assembly satellite, vedere l'articolo Recupero di risorse.

<nodo del file di configurazione satelliteassemblies>

Nota

Questa sezione è specifica per le app .NET Framework.

Per i file eseguibili distribuiti ed eseguiti da un sito Web (file HREF .exe), l'oggetto ResourceManager può eseguire il probe per gli assembly satellite sul Web, che può danneggiare le prestazioni dell'app. Per eliminare il problema di prestazioni, è possibile limitare questo probe agli assembly satellite distribuiti con l'app. A tale scopo, si crea un <satelliteassemblies> nodo nel file di configurazione dell'app per specificare che è stato distribuito un set specifico di impostazioni cultura per l'app e che l'oggetto ResourceManager non deve provare a eseguire il probe delle impostazioni cultura non elencate in tale nodo.

Nota

L'alternativa preferita alla creazione di un <satelliteassemblies> nodo consiste nell'usare la funzionalità Manifesto distribuzione ClickOnce.

Nel file di configurazione dell'app creare una sezione simile alla seguente:

<?xml version ="1.0"?>
<configuration>
  <satelliteassemblies>
    <assembly name="MainAssemblyName, Version=versionNumber, Culture=neutral, PublicKeyToken=null|yourPublicKeyToken">
      <culture>cultureName1</culture>
      <culture>cultureName2</culture>
      <culture>cultureName3</culture>
    </assembly>
  </satelliteassemblies>
</configuration>

Modificare queste informazioni di configurazione come indicato di seguito:

  • Specificare uno o più <assembly> nodi per ogni assembly principale distribuito, in cui ogni nodo specifica un nome di assembly completo. Specificare il nome dell'assembly principale al posto di MainAssemblyName e specificare i valori dell'attributo , PublicKeyTokene Culture corrispondenti all'assembly Versionprincipale.

    Per l'attributo Version specificare il numero di versione dell'assembly. Ad esempio, la prima versione dell'assembly potrebbe essere il numero di versione 1.0.0.0.

    Per l'attributo, specificare la parola chiave null se l'assembly PublicKeyToken non è stato firmato con un nome sicuro o specificare il token di chiave pubblica se è stato firmato l'assembly.

    Per l'attributo Culture , specificare la parola chiave neutral per designare l'assembly principale e fare in modo che la ResourceManager classe eseperi solo le impostazioni cultura elencate nei <culture> nodi.

    Per altre informazioni sui nomi di assembly completi, vedere l'articolo Nomi assembly. Per altre informazioni sugli assembly con nome sicuro, vedere l'articolo Creare e usare assembly con nome sicuro.

  • Specificare uno o più <culture> nodi con un nome di impostazioni cultura specifico, ad esempio "fr-FR" o un nome di impostazioni cultura neutre, ad esempio "fr".

Se le risorse sono necessarie per qualsiasi assembly non elencato nel <satelliteassemblies> nodo, la classe esegue il ResourceManager probe per le impostazioni cultura usando regole di probe standard.

App di Windows 8.x

Importante

Anche se la ResourceManager classe è supportata nelle app di Windows 8.x, non è consigliabile usarla. Usare questa classe solo quando si sviluppano progetti della libreria di classi portabile che possono essere usati con le app di Windows 8.x. Per recuperare le risorse dalle app di Windows 8.x, usare invece la classe Windows.ApplicationModel.Resources.ResourceLoader .

Per le app di Windows 8.x, la ResourceManager classe recupera le risorse dai file PRI (Package Resource Index). Un singolo file PRI (file PRI del pacchetto dell'applicazione) contiene le risorse sia per le impostazioni cultura predefinite che per le impostazioni cultura localizzate. Usare l'utilità MakePRI per creare un file PRI da uno o più file di risorse in formato di risorsa XML (resw). Per le risorse incluse in un progetto di Visual Studio, Visual Studio gestisce automaticamente il processo di creazione e creazione del pacchetto del file PRI. È quindi possibile usare la classe .NET ResourceManager per accedere alle risorse dell'app o della libreria.

Puoi creare un'istanza di un ResourceManager oggetto per un'app di Windows 8.x nello stesso modo in cui fai per un'app desktop.

È quindi possibile accedere alle risorse per impostazioni cultura specifiche passando il nome della risorsa da recuperare al GetString(String) metodo . Per impostazione predefinita, questo metodo restituisce la risorsa per le impostazioni cultura determinate dalle impostazioni cultura correnti dell'interfaccia utente del thread che ha effettuato la chiamata. È anche possibile recuperare le risorse per impostazioni cultura specifiche passando il nome della risorsa e un CultureInfo oggetto che rappresenta le impostazioni cultura la cui risorsa deve essere recuperata al GetString(String, CultureInfo) metodo . Se non è possibile trovare la risorsa per le impostazioni cultura correnti dell'interfaccia utente o le impostazioni cultura specificate, gestione risorse usa un elenco di fallback della lingua dell'interfaccia utente per individuare una risorsa appropriata.

Esempi

Nell'esempio seguente viene illustrato come usare impostazioni cultura esplicite e impostazioni cultura dell'interfaccia utente correnti implicite per ottenere risorse stringa da un assembly principale e da un assembly satellite. Per altre informazioni, vedere la sezione "Percorsi directory per assembly satellite non installati nella Global Assembly Cache" dell'argomento Creazione di assembly satellite.

Per eseguire questo esempio:

  1. Nella directory dell'app creare un file denominato rmc.txt che contiene le stringhe di risorse seguenti:

    day=Friday
    year=2006
    holiday="Cinco de Mayo"
    
  2. Usare il generatore di file di risorse per generare il file di risorse rmc.resources dal file di input rmc.txt come indicato di seguito:

    resgen rmc.txt
    
  3. Creare una sottodirectory della directory dell'app e denominarla "es-MX". Si tratta del nome delle impostazioni cultura dell'assembly satellite che verrà creato nei tre passaggi successivi.

  4. Creare un file denominato rmc.es-MX.txt nella directory es-MX contenente le stringhe di risorse seguenti:

    day=Viernes
    year=2006
    holiday="Cinco de Mayo"
    
  5. Usare il generatore di file di risorse per generare il file di risorse rmc.es-MX.resources dal file di input rmc.es-MX.txt come indicato di seguito:

    resgen rmc.es-MX.txt
    
  6. Si supponga che il nome file per questo esempio sia rmc.vb o rmc.cs. Copiare il codice sorgente seguente in un file. Compilarlo e incorporare quindi il file di risorse dell'assembly principale rmc.resources nell'assembly eseguibile. Se si usa il compilatore Visual Basic, la sintassi è:

    vbc rmc.vb /resource:rmc.resources
    

    La sintassi corrispondente per il compilatore C# è:

    csc /resource:rmc.resources rmc.cs
    
  7. Usare Assembly Linker per creare un assembly satellite. Se il nome di base dell'app è rmc, il nome dell'assembly satellite deve essere rmc.resources.dll. L'assembly satellite deve essere creato nella directory es-MX. Se es-MX è la directory corrente, usare questo comando:

    al /embed:rmc.es-MX.resources /c:es-MX /out:rmc.resources.dll
    
  8. Eseguire rmc.exe per ottenere e visualizzare le stringhe di risorse incorporate.

    using System;
    using System.Globalization;
    using System.Resources;
    
    class Example2
    {
        public static void Main()
        {
            string day;
            string year;
            string holiday;
            string celebrate = "{0} will occur on {1} in {2}.\n";
    
            // Create a resource manager.
            ResourceManager rm = new ResourceManager("rmc",
                                     typeof(Example).Assembly);
    
            Console.WriteLine("Obtain resources using the current UI culture.");
    
            // Get the resource strings for the day, year, and holiday
            // using the current UI culture.
            day = rm.GetString("day");
            year = rm.GetString("year");
            holiday = rm.GetString("holiday");
            Console.WriteLine(celebrate, holiday, day, year);
    
            // Obtain the es-MX culture.
            CultureInfo ci = new CultureInfo("es-MX");
    
            Console.WriteLine("Obtain resources using the es-MX culture.");
    
            // Get the resource strings for the day, year, and holiday
            // using the specified culture.
            day = rm.GetString("day", ci);
            year = rm.GetString("year", ci);
            holiday = rm.GetString("holiday", ci);
            // ---------------------------------------------------------------
            // Alternatively, comment the preceding 3 code statements and
            // uncomment the following 4 code statements:
            // ----------------------------------------------------------------
            // Set the current UI culture to "es-MX" (Spanish-Mexico).
            //    Thread.CurrentThread.CurrentUICulture = ci;
    
            // Get the resource strings for the day, year, and holiday
            // using the current UI culture. Use those strings to
            // display a message.
            //    day  = rm.GetString("day");
            //    year = rm.GetString("year");
            //    holiday = rm.GetString("holiday");
            // ---------------------------------------------------------------
    
            // Regardless of the alternative that you choose, display a message
            // using the retrieved resource strings.
            Console.WriteLine(celebrate, holiday, day, year);
        }
    }
    /*
    This example displays the following output:
    
       Obtain resources using the current UI culture.
       "5th of May" will occur on Friday in 2006.
    
       Obtain resources using the es-MX culture.
       "Cinco de Mayo" will occur on Viernes in 2006.
    */
    
    Imports System.Resources
    Imports System.Reflection
    Imports System.Threading
    Imports System.Globalization
    
    Class Example4
        Public Shared Sub Main()
            Dim day As String
            Dim year As String
            Dim holiday As String
            Dim celebrate As String = "{0} will occur on {1} in {2}." & vbCrLf
    
            ' Create a resource manager. 
            Dim rm As New ResourceManager("rmc", GetType(Example4).Assembly)
    
            Console.WriteLine("Obtain resources using the current UI culture.")
    
            ' Get the resource strings for the day, year, and holiday 
            ' using the current UI culture. 
            day = rm.GetString("day")
            year = rm.GetString("year")
            holiday = rm.GetString("holiday")
            Console.WriteLine(celebrate, holiday, day, year)
    
            ' Obtain the es-MX culture.
            Dim ci As New CultureInfo("es-MX")
    
            Console.WriteLine("Obtain resources using the es-MX culture.")
    
            ' Get the resource strings for the day, year, and holiday 
            ' using the es-MX culture.  
            day = rm.GetString("day", ci)
            year = rm.GetString("year", ci)
            holiday = rm.GetString("holiday", ci)
    
            ' ---------------------------------------------------------------
            ' Alternatively, comment the preceding 3 code statements and 
            ' uncomment the following 4 code statements:
            ' ----------------------------------------------------------------
            ' Set the current UI culture to "es-MX" (Spanish-Mexico).
            '    Thread.CurrentThread.CurrentUICulture = ci
            ' Get the resource strings for the day, year, and holiday 
            ' using the current UI culture. 
            '    day  = rm.GetString("day")
            '    year = rm.GetString("year")
            '    holiday = rm.GetString("holiday")
            ' ---------------------------------------------------------------
    
            ' Regardless of the alternative that you choose, display a message 
            ' using the retrieved resource strings.
            Console.WriteLine(celebrate, holiday, day, year)
        End Sub
    End Class
    ' This example displays the following output:
    'Obtain resources using the current UI culture.
    '"5th of May" will occur on Friday in 2006.
    '
    'Obtain resources using the es-MX culture.
    '"Cinco de Mayo" will occur on Viernes in 2006.