Creare assembly satellite per le app .NET

I file di risorse svolgono un ruolo centrale nelle applicazioni localizzate. Consentono a un'applicazione di visualizzare stringhe, immagini e altri dati nella lingua e nelle impostazioni cultura dell'utente e fornire dati alternativi se le risorse per la lingua o le impostazioni cultura dell'utente non sono disponibili. .NET usa un modello hub-and-spoke per individuare e recuperare risorse localizzate. L'hub è l'assembly principale che contiene il codice eseguibile non localizzabile e le risorse di un singolo set di impostazioni cultura, denominate impostazioni cultura neutre o predefinite. Le impostazioni cultura predefinite sono le impostazioni cultura di fallback per l'applicazione; viene usato quando non sono disponibili risorse localizzate. Per designare le impostazioni cultura predefinite dell'applicazione, si usa l'attributo NeutralResourcesLanguageAttribute. Ogni spoke si connette a un assembly satellite contenente le risorse relative a impostazioni cultura specifiche, ma non contiene codice. Poiché gli assembly satellite non fanno parte dell'assembly principale, è possibile aggiornare o sostituire facilmente le risorse corrispondenti a impostazioni cultura specifiche senza sostituire l'assembly principale per l'applicazione.

Nota

Le risorse delle impostazioni cultura predefinite di un'applicazione possono anche essere archiviate in un assembly satellite. A tale scopo, si assegna all'attributo NeutralResourcesLanguageAttribute un valore di UltimateResourceFallbackLocation.Satellite.

Nome e posizione dell'assembly satellite

Requisito del modello hub e spoke è che le risorse vengano inserite in posizioni specifiche perché possano essere individuate e usate con facilità. Se le risorse non vengono compilate e denominate come previsto o se non vengono inserite nelle posizioni corrette, Common Language Runtime non sarà in grado di individuarle e userà invece le risorse delle impostazioni cultura predefinite. Gestione risorse .NET è rappresentato dal ResourceManager tipo e viene usato per accedere automaticamente alle risorse localizzate. Gestione risorse richiede quanto segue:

  • Un assembly satellite singolo deve includere tutte le risorse relative a impostazioni cultura particolari. In altre parole, è necessario compilare più file.txt o resx in un singolo file binario .resources .

  • Nella directory dell'applicazione deve esistere una sottodirectory separata per ognuna delle impostazioni cultura localizzate. In tali sottodirectory devono essere archiviate le risorse delle rispettive impostazioni cultura. Il nome della sottodirectory deve essere lo stesso delle impostazioni cultura. In alternativa, è possibile archiviare gli assembly satellite nella Global Assembly Cache. In questo caso, il componente delle informazioni delle impostazioni cultura del nome sicuro dell'assembly deve indicare le impostazioni cultura corrispondenti. Per altre informazioni, vedere Installare assembly satellite nella Global Assembly Cache.

    Nota

    Se l'applicazione include risorse per impostazioni cultura secondarie, inserire le impostazioni cultura secondarie in una sottodirectory separata all'interno della directory dell'applicazione. Non inserire impostazioni cultura secondarie all'interno di sottodirectory della directory delle impostazioni cultura principali.

  • L'assembly satellite deve avere lo stesso nome dell'applicazione e deve usare l'estensione di file ".resources.dll". Ad esempio, se un'applicazione è denominata Example.exe, il nome di ogni assembly satellite deve essere Example.resources.dll. Il nome dell'assembly satellite non indica le impostazioni cultura dei file di risorse. L'assembly satellite, tuttavia, viene visualizzato in una directory che specifica le impostazioni cultura.

  • Le informazioni sulle impostazioni cultura dell'assembly satellite devono essere incluse nei metadati dell'assembly. Per archiviare il nome delle impostazioni cultura nei metadati dell'assembly satellite, specificare l'opzione /culture quando si incorporano le risorse nell'assembly satellite tramite Assembly Linker.

Nella figura seguente viene illustrata una struttura di directory di esempio e i requisiti di posizione per le applicazioni che non si installano nella global assembly cache. Gli elementi con estensioni.txt e .resources non verranno forniti con l'applicazione finale. Questi sono file di risorse intermedi usati per creare gli assembly di risorse satellite finali. In questo esempio è possibile sostituire i file resx per i file .txt . Per altre informazioni, vedere Pacchetto e distribuzione delle risorse.

L'immagine seguente mostra la directory degli assembly satellite:

una directory di assembly satellite con sottodirectory di impostazioni cultura localizzate.

Compilare assembly satellite

Si usa Generatore file di risorse (resgen.exe) per compilare file di testo o FILE XML (con estensione resx) contenenti risorse nei file con estensione resources binari. Si usa quindi Assembly Linker (al.exe) per compilare i file .resources in assembly satellite. al.exe crea un assembly dai file con estensione resources specificati. Gli assembly satellite possono contenere solo risorse; non possono contenere codice eseguibile.

Il comando al.exe seguente crea un assembly satellite per l'applicazione Example dalla stringa di file di risorse tedesca stringhe.de.resources.

al -target:lib -embed:strings.de.resources -culture:de -out:Example.resources.dll

Il comando al.exe seguente crea anche un assembly satellite per l'applicazione Example dalla stringa di file.de.resources. L'opzione /template causa l'ereditarietà di tutti i metadati dell'assembly satellite, ad eccezione delle relative informazioni cultura dall'assembly padre (Example.dll).

al -target:lib -embed:strings.de.resources -culture:de -out:Example.resources.dll -template:Example.dll

Nella tabella seguente vengono descritte le opzioni dial.exe usate in questi comandi in modo più dettagliato:

Opzione Descrizione
-target:lib Specifica che l'assembly satellite deve essere compilato in un file di libreria con estensione dll. Poiché un assembly satellite non contiene codice eseguibile e non è l'assembly principale di un'applicazione, è necessario salvare gli assembly satellite come DLL.
-embed:strings.de.resources Specifica il nome del file di risorse da incorporare quando al.exe compila l'assembly. È possibile incorporare più file con estensione resources in un assembly satellite. Se si segue il modello hub e spoke, però, è necessario compilare un assembly satellite per ognuna delle impostazioni cultura. È tuttavia possibile creare file con estensione resources separati per le stringhe e gli oggetti.
-culture:de Specifica le impostazioni cultura della risorsa da compilare. Common Language Runtime usa queste informazioni durante la ricerca delle risorse per impostazioni cultura specifiche. Se si omette questa opzione, al.exe continuerà a compilare la risorsa, ma il runtime non sarà in grado di trovarlo quando un utente lo richiede.
-out:Example.resources.dll Specifica il nome del file di output. Il nome deve seguire lo standard di denominazione nomeBase.resources.estensione, dove nomeBase è il nome dell'assembly principale ed estensione è un'estensione di file valida, ad esempio dll. Il runtime non è in grado di determinare le impostazioni cultura di un assembly satellite in base al nome del file di output; è necessario usare l'opzione /culture per specificarla.
-template:Example.dll Specifica l'assembly dal quale l'assembly satellite deve ereditare tutti i metadati, ad eccezione del campo relativo alle impostazioni cultura. Questa opzione influisce sugli assembly satellite solo se si specifica un assembly con un nome sicuro.

Per un elenco completo delle opzioni disponibili con al.exe, vedere Assembly Linker (al.exe).

Nota

Potrebbero verificarsi momenti in cui si vuole usare l'attività MSBuild di .NET Core per compilare assembly satellite, anche se si usa .NET Framework. Ad esempio, è possibile usare l'opzione deterministica del compilatore C# per poter confrontare gli assembly da compilazioni diverse. In questo caso, impostare GenerateSatelliteAssembliesForCore su true nel file con estensione csproj per generare assembly satellite usando csc.exe anziché Al.exe (Assembly Linker).

<Project>
    <PropertyGroup>
        <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
    </PropertyGroup>
</Project>

L'attività MSBuild di .NET Core usa csc.exe anziché al.exe per generare assembly satellite, per impostazione predefinita. Per altre informazioni, vedere Rendere più semplice scegliere la generazione di assembly satellite "Core".

Esempio di assembly satellite

Di seguito è riportato un semplice esempio di tipo "Hello world" che visualizza una finestra di messaggio contenente un saluto localizzato. L'esempio include le risorse per le impostazioni cultura inglesi (Stati Uniti), francesi (Francia) e russe (Russia). Le impostazioni cultura inglesi sono le impostazioni cultura di fallback. Per creare l'esempio, eseguire le operazioni seguenti:

  1. Creare un file di risorse denominato Greeting.resx o Greeting.txt per contenere la risorsa per le impostazioni cultura predefinite. Archiviare una singola stringa denominata HelloString il cui valore è "Hello world!" in questo file.

  2. Per impostare le impostazioni cultura inglesi (en) come predefinite per l'applicazione, aggiungere l'attributo System.Resources.NeutralResourcesLanguageAttribute seguente al file AssemblyInfo dell'applicazione o al file di codice sorgente principale che verrà compilato nell'assembly principale dell'applicazione.

    [assembly: NeutralResourcesLanguage("en")]
    
    <Assembly: NeutralResourcesLanguage("en")>
    
  3. Aggiungere il supporto per impostazioni cultura aggiuntive (en-US, fr-FRe ru-RU) all'applicazione come indicato di seguito:

    • Per supportare le en-US impostazioni cultura o inglese (Stati Uniti), creare un file di risorse denominato Greeting.en-US.resx o Greeting.en-US.txte archiviarlo in una singola stringa denominata HelloString il cui valore è "Hi world!".

    • Per supportare le fr-FR impostazioni cultura francese (Francia), creare un file di risorse denominato Greeting.fr-FR.resx o Greeting.fr-FR.txte archiviarlo in una singola stringa denominata HelloString il cui valore è "Salut tout le monde!".

    • Per supportare le ru-RU impostazioni cultura russo (Russia), creare un file di risorse denominato Greeting.ru-RU.resx o Greeting.ru-RU.txte archiviarlo in una singola stringa denominata HelloString il cui valore è "Всем привет!".

  4. Usare resgen.exe per compilare ogni file di risorse XML o di testo in un file binario con estensione resources . L'output è un set di file con lo stesso nome di file radice dei file con estensione resx o .txt , ma un'estensione . resources . Se si crea l'esempio con Visual Studio, il processo di compilazione viene gestito automaticamente. Se non si usa Visual Studio, eseguire i comandi seguenti per compilare i file con estensione resx nei file con estensione resources :

    resgen Greeting.resx
    resgen Greeting.en-us.resx
    resgen Greeting.fr-FR.resx
    resgen Greeting.ru-RU.resx
    

    Se le risorse si trovano in file di testo anziché file XML, sostituire l'estensione resx con .txt.

  5. Compilare il codice sorgente seguente con le risorse per le impostazioni cultura predefinite nell'assembly principale dell'applicazione:

    Importante

    Se per creare l'esempio si usa la riga di comando anziché Visual Studio, è necessario modificare la chiamata al costruttore della classe ResourceManager come segue: ResourceManager rm = new ResourceManager("Greeting", typeof(Example).Assembly);

    using System;
    using System.Globalization;
    using System.Reflection;
    using System.Resources;
    using System.Threading;
    using System.Windows.Forms;
    
    class Example
    {
       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;
    
          try {
             CultureInfo newCulture = new CultureInfo(cultures[cultureNdx]);
             Thread.CurrentThread.CurrentCulture = newCulture;
             Thread.CurrentThread.CurrentUICulture = newCulture;
             ResourceManager rm = new ResourceManager("Example.Greeting",
                                                      typeof(Example).Assembly);
             string greeting = String.Format("The current culture is {0}.\n{1}",
                                             Thread.CurrentThread.CurrentUICulture.Name,
                                             rm.GetString("HelloString"));
    
             MessageBox.Show(greeting);
          }
          catch (CultureNotFoundException e) {
             Console.WriteLine("Unable to instantiate culture {0}", e.InvalidCultureName);
          }
          finally {
             Thread.CurrentThread.CurrentCulture = originalCulture;
             Thread.CurrentThread.CurrentUICulture = originalCulture;
          }
       }
    }
    
    Imports System.Globalization
    Imports System.Resources
    Imports System.Threading
    
    Module Module1
    
        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
    
            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, My.Resources.Greetings.HelloString)
    
                MsgBox(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
    

    Se l'applicazione è denominata Esempio e si esegue la compilazione dalla riga di comando, il comando per il compilatore C# è:

    csc Example.cs -res:Greeting.resources
    

    Per il compilatore Visual Basic il comando corrispondente è:

    vbc Example.vb -res:Greeting.resources
    
  6. Creare una sottodirectory nella directory principale dell'applicazione per ognuna delle impostazioni cultura localizzate supportate dall'applicazione. È necessario creare una sottodirectory en-US, una fr-FR e una sottodirectory ru-UR . Visual Studio crea queste sottodirectory automaticamente nell'ambito del processo di compilazione.

  7. Incorporare i singoli file con estensione risorse specifiche delle impostazioni cultura in assembly satellite e salvarli nella directory appropriata. Il comando per eseguire questa operazione per ogni file con estensione resources è:

    al -target:lib -embed:Greeting.culture.resources -culture:culture -out:culture\Example.resources.dll
    

    dove culture è il nome delle impostazioni cultura le cui risorse sono contenute dall'assembly satellite. Visual Studio gestisce questo processo automaticamente.

È quindi possibile eseguire l'esempio. Questo effettua una selezione casuale tra le impostazioni cultura supportate, definisce le impostazioni cultura selezionate come correnti e visualizza il saluto localizzato.

Installare assembly satellite nella Global Assembly Cache

Invece di installare gli assembly in una sottodirectory locale dell'applicazione, è possibile installarli nella Global Assembly Cache. Ciò è particolarmente utile se alcuni assembly di librerie di classi e di risorse di librerie di classi vengono usati da più applicazioni.

L'installazione di assembly nella Global Assembly Cache richiede che gli assembly abbiano nomi sicuri. Gli assembly con nomi sicuri, firmati con una coppia di chiavi pubblica/privata valida, contengono informazioni sulla versione usate dal runtime allo scopo di determinare l'assembly da usare per soddisfare una richiesta di associazione. Per altre informazioni sui nomi sicuri e sul controllo delle versioni, vedere Controllo delle versioni degli assembly. Per altre informazioni sui nomi sicuri, vedere Assembly con nome sicuro.

Quando si sviluppa un'applicazione, è improbabile che si abbia accesso alla coppia di chiavi pubblica/privata finale. Per installare un assembly satellite nella global assembly cache e assicurarsi che funzioni come previsto, è possibile usare una tecnica denominata firma ritardata. Quando si ritarda la firma di un assembly, al momento della compilazione viene riservato spazio nel file per la firma con nome sicuro. La firma effettiva viene posticipata al momento in cui la coppia di chiavi pubblica/privata finale è disponibile. Per altre informazioni sulla firma ritardata, vedere Ritardare la firma di un assembly.

Ottenere la chiave pubblica

Per ritardare la firma di un assembly, è necessario avere accesso alla chiave pubblica. È possibile ottenere la chiave pubblica reale dall'organizzazione dell'azienda che eseguirà la firma finale o creare una chiave pubblica usando lo strumento Nome sicuro (sn.exe).

Il comando Sn.exe seguente crea una coppia di chiavi pubblica/privata di test. L'opzione –k specifica che Sn.exe deve creare una nuova coppia di chiavi e salvarla in un file denominato TestKeyPair.snk.

sn –k TestKeyPair.snk

È possibile estrarre la chiave pubblica dal file che contiene la coppia di chiavi di test. Il comando seguente estrae la chiave pubblica da TestKeyPair.snk e la salva in PublicKey.snk:

sn –p TestKeyPair.snk PublicKey.snk

Ritardare la firma di un assembly

Dopo aver ottenuto o creato la chiave pubblica, usare Assembly Linker (al.exe) per compilare l'assembly e specificare la firma ritardata.

Il comando al.exe seguente crea un assembly satellite con nome sicuro per l'applicazione StringLibrary dal file strings.ja.resources :

al -target:lib -embed:strings.ja.resources -culture:ja -out:StringLibrary.resources.dll -delay+ -keyfile:PublicKey.snk

L'opzione -delay+ specifica che Assembly Linker deve ritardare la firma dell'assembly. L'opzione -keyfile specifica il nome del file di chiave che contiene la chiave pubblica da usare per ritardare la firma dell'assembly.

Nuova firma di un assembly

Prima di distribuire l'applicazione, è necessario firmare nuovamente l'assembly satellite con ritardo della firma con la coppia di chiavi reale. È possibile eseguire questa operazione usando Sn.exe.

Il comando Sn.exe seguente firma StringLibrary.resources.dll con la coppia di chiavi archiviata nel file RealKeyPair.snk. L'opzione -R specifica che un assembly firmato in precedenza deve essere firmato nuovamente o che un assembly con ritardo della firma deve essere firmato.

sn –R StringLibrary.resources.dll RealKeyPair.snk

Installare un assembly satellite nella Global Assembly Cache

Durante la ricerca di risorse nell'ambito del processo di fallback delle risorse, il runtime prima cerca nella Global Assembly Cache. Per altre informazioni, vedere la sezione "Processo di fallback delle risorse" del pacchetto e della distribuzione delle risorse. Non appena un assembly satellite viene firmato con un nome sicuro, può essere installato nella global assembly cache usando lo strumento Global Assembly Cache (gacutil.exe).

Il comando Gacutil.exe seguente installa StringLibrary.resources.dll* nella global assembly cache:

gacutil -i:StringLibrary.resources.dll

L'opzione /i specifica che Gacutil.exe deve installare l'assembly specificato nella global assembly cache. Dopo l'installazione dell'assembly satellite nella cache, le risorse in esso contenute diventano disponibili per tutte le applicazioni progettate per l'uso dell'assembly satellite.

Risorse nella Global Assembly Cache: un esempio

Nell'esempio seguente viene usato un metodo in una libreria di classi .NET per estrarre e restituire un saluto localizzato da un file di risorse. La libreria e le relative risorse sono registrate nella Global Assembly Cache. L'esempio include risorse per le impostazioni cultura inglesi (Stati Uniti), francesi (Francia), russe (Russia) e inglesi. Le impostazioni cultura predefinite corrispondono a quelle inglesi e le risorse corrispondenti sono archiviate nell'assembly principale. L'esempio inizialmente ritarda la libreria e i relativi assembly satellite con una chiave pubblica, quindi li firma nuovamente con una coppia di chiavi pubblica/privata. Per creare l'esempio, eseguire le operazioni seguenti:

  1. Se non si usa Visual Studio, usare il comando Strong Name Tool (Sn.exe) seguente per creare una coppia di chiavi pubblica/privata denominata ResKey.snk:

    sn –k ResKey.snk
    

    Se si usa Visual Studio, usare la scheda Firma della finestra di dialogo Proprietà progetto per generare il file di chiave.

  2. Usare il comando Strumento nome sicuro (Sn.exe) seguente per creare un file di chiave pubblica denominato PublicKey.snk:

    sn –p ResKey.snk PublicKey.snk
    
  3. Creare un file di risorse denominato Strings.resx per contenere la risorsa per le impostazioni cultura predefinite. Archiviare una singola stringa denominata Greeting il cui valore è "Come si fa?" in tale file.

  4. Per impostare "en" come impostazioni cultura predefinite dell'applicazione, aggiungere l'attributo System.Resources.NeutralResourcesLanguageAttribute seguente al file AssemblyInfo dell'applicazione o al file di codice sorgente principale che verrà compilato nell'assembly principale dell'applicazione:

    [assembly:NeutralResourcesLanguageAttribute("en")]
    
    <Assembly: NeutralResourcesLanguageAttribute("en")>
    
  5. Aggiungere all'applicazione il supporto per le impostazioni cultura aggiuntive (en-US, fr-FR e ru-RU) come segue:

    • Per supportare le impostazioni cultura "en-US" o inglese (Stati Uniti), creare un file di risorse denominato Strings.en-US.resx o Strings.en-US.txte archiviarlo in una singola stringa denominata Greeting il cui valore è "Hello!".

    • Per supportare le impostazioni cultura "fr-FR" o francese (Francia), creare un file di risorse denominato Strings.fr-FR.resx o Strings.fr-FR.txt e archiviarlo in una singola stringa denominata Greeting il cui valore è "Bon jour!".

    • Per supportare le impostazioni cultura "ru-UR" o russo (Russia), creare un file di risorse denominato Strings.ru-UR.resx o Strings.ru-RU.txt e archiviarlo in una singola stringa denominata Greeting il cui valore è "Привет!".

  6. Usare resgen.exe per compilare ogni file di risorse XML o testo in un file binario con estensione resources. L'output è un set di file con lo stesso nome di file radice dei file con estensione resx o .txt , ma un'estensione . resources . Se si crea l'esempio con Visual Studio, il processo di compilazione viene gestito automaticamente. Se non si usa Visual Studio, eseguire il comando seguente per compilare i file con estensione resx nei file con estensione resources :

    resgen filename
    

    Dove nome file è il percorso facoltativo, il nome del file e l'estensione del file con estensione resx o testo.

  7. Compilare il codice sorgente seguente per StringLibrary.vb o StringLibrary.cs insieme alle risorse per le impostazioni cultura predefinite in un assembly di libreria con segno di ritardo denominato StringLibrary.dll:

    Importante

    Se per creare l'esempio si usa la riga di comando anziché Visual Studio, è necessario modificare la chiamata al costruttore della classe ResourceManager in ResourceManager rm = new ResourceManager("Strings",typeof(Example).Assembly);.

    using System;
    using System.Globalization;
    using System.Reflection;
    using System.Resources;
    using System.Threading;
    
    [assembly:NeutralResourcesLanguageAttribute("en")]
    
    public class StringLibrary
    {
       public string GetGreeting()
       {
          ResourceManager rm = new ResourceManager("Strings",
                               Assembly.GetAssembly(typeof(StringLibrary)));
          string greeting = rm.GetString("Greeting");
          return greeting;
       }
    }
    
    Imports System.Globalization
    Imports System.Reflection
    Imports System.Resources
    Imports System.Threading
    
    <Assembly: NeutralResourcesLanguageAttribute("en")>
    
    Public Class StringLibrary
        Public Function GetGreeting() As String
            Dim rm As New ResourceManager("Strings", _
                                          Assembly.GetAssembly(GetType(StringLibrary)))
            Dim greeting As String = rm.GetString("Greeting")
            Return greeting
        End Function
    End Class
    

    La riga di comando per il compilatore C# è:

    csc -t:library -resource:Strings.resources -delaysign+ -keyfile:publickey.snk StringLibrary.cs
    

    Per il compilatore Visual Basic il comando corrispondente è:

    vbc -t:library -resource:Strings.resources -delaysign+ -keyfile:publickey.snk StringLibrary.vb
    
  8. Creare una sottodirectory nella directory principale dell'applicazione per ognuna delle impostazioni cultura localizzate supportate dall'applicazione. È necessario creare una sottodirectory en-US, una fr-FR e una sottodirectory ru-UR . Visual Studio crea queste sottodirectory automaticamente nell'ambito del processo di compilazione. Poiché tutti gli assembly satellite hanno lo stesso nome di file, le sottodirectory vengono usate per archiviare singoli assembly satellite specifici delle impostazioni cultura fino a quando non vengono firmati con una coppia di chiavi pubblica/privata.

  9. Incorporare i singoli file con estensione risorse specifiche delle impostazioni cultura in assembly satellite con firma ritardata e salvarli nella directory appropriata. Il comando per eseguire questa operazione per ogni file con estensione resources è:

    al -target:lib -embed:Strings.culture.resources -culture:culture -out:culture\StringLibrary.resources.dll -delay+ -keyfile:publickey.snk
    

    dove culture è il nome delle impostazioni cultura. In questo esempio i nomi delle impostazioni cultura sono en-US, fr-FR e ru-RU.

  10. Rifirmare StringLibrary.dll usando lo strumento Nome sicuro (sn.exe) come indicato di seguito:

    sn –R StringLibrary.dll RealKeyPair.snk
    
  11. Firmare nuovamente i singoli assembly satellite. A tale scopo, usare lo strumento Nome sicuro (sn.exe) come indicato di seguito per ogni assembly satellite:

    sn –R StringLibrary.resources.dll RealKeyPair.snk
    
  12. Registrare StringLibrary.dll e ognuno dei relativi assembly satellite nella global assembly cache usando il comando seguente:

    gacutil -i filename
    

    dove filename rappresenta il nome del file da registrare.

  13. Se si usa Visual Studio, creare un nuovo progetto applicazione console denominato Example, aggiungere un riferimento a StringLibrary.dll e al codice sorgente seguente e compilarlo.

    using System;
    using System.Globalization;
    using System.Threading;
    
    public class Example
    {
       public static void Main()
       {
          string[] cultureNames = { "en-GB", "en-US", "fr-FR", "ru-RU" };
          Random rnd = new Random();
          string cultureName = cultureNames[rnd.Next(0, cultureNames.Length)];
          Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName);
          Console.WriteLine("The current UI culture is {0}",
                            Thread.CurrentThread.CurrentUICulture.Name);
          StringLibrary strLib = new StringLibrary();
          string greeting = strLib.GetGreeting();
          Console.WriteLine(greeting);
       }
    }
    
    Imports System.Globalization
    Imports System.Threading
    
    Module Example
        Public Sub Main()
            Dim cultureNames() As String = {"en-GB", "en-US", "fr-FR", "ru-RU"}
            Dim rnd As New Random()
            Dim cultureName As String = cultureNames(rnd.Next(0, cultureNames.Length))
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName)
            Console.WriteLine("The current UI culture is {0}",
                              Thread.CurrentThread.CurrentUICulture.Name)
            Dim strLib As New StringLibrary()
            Dim greeting As String = strLib.GetGreeting()
            Console.WriteLine(greeting)
        End Sub
    End Module
    

    Per eseguire la compilazione dalla riga di comando, per il compilatore C# usare il comando seguente:

    csc Example.cs -r:StringLibrary.dll
    

    La riga di comando per il compilatore Visual Basic è:

    vbc Example.vb -r:StringLibrary.dll
    
  14. Eseguire Example.exe.

Vedi anche