2009-11-24 15 views
15

Ci sono un sacco di tutorial su come creare file RESX multilingua e su come creare assembly satellite con AL.exe, ma non ho trovato un esempio funzionante come incorporare file RESX/Resources/satellite-DLL in un singolo file EXE e distribuire interi app multilingua come tale EXE.Come incorporare file multilingua * .resx (o * .resources) in un unico file EXE?

Ho provato a usare ilmerge.exe, ma sembra che non funzioni per più DLL con lo stesso nome (le DLL di cultura satellite hanno nomi identici, originariamente residenti in diverse sottodirectory che prendono il nome dalla cultura).

Inoltre non so come creare un'istanza ResourceManager per lavorare con le risorse incorporate.

Il mio obiettivo è di abilitare il passaggio dinamico tra un insieme di lingue chiuso e predefinito. Ho bisogno della classe/metodo che otterrà la stringa di cultura (cioè "de-DE"), il nome della risorsa (ad esempio "CancelText") e restituirà il testo tradotto basato su incorporato resx/resource/dll.

Sto usando VS2008, si noti quale impostazione per "azione build" è necessaria nel foglio delle proprietà dei file resx/risorse. Esempio di codice di lavoro o collegamento al progetto di esercitazione sarebbe il migliore.

+1

So che è raccapricciante riattivare un thread così vecchio, ma sono interessato a scoprire se hai risolto il problema e se sì, come? Sei ancora, a questa data, usando il tuo approccio (la risposta che hai dato qui sotto)? Sto lavorando a un progetto simile in VS 2012 e vorrei combinare le mie DLL di risorse linguistiche nel file assembly/exe principale, mentre utilizzo ancora ResourceManager per passare da tedesco a inglese. Grazie! – Sebastian

+0

@Sebastian Non ho esplorato in nessun altro modo, per favore condividi se ne trovi uno migliore – tomash

risposta

8

La mia soluzione: il programma contiene solo un file di risorse di lingua predefinito (resx). Tutte le altre lingue sono compilate da .resx a .resources e incorporate come file di risorse. Importante! Ho cambiato estensione perché ".resources" è riconosciuto come un tipo speciale di risorsa, quindi i miei file francesi sono denominati "PIAE.LangResources.fr".

Ecco semplice codice per recuperare stringa tradotta (dovrebbe essere migliorato con i valori di cache di risorse):

internal static string GetString(string str, string lang) 
    { 

     if (string.IsNullOrEmpty(str)) throw new ArgumentNullException("empty language query string"); 
     if (string.IsNullOrEmpty(lang)) throw new ArgumentNullException("no language resource given"); 

     // culture-specific file, i.e. "LangResources.fr" 
     Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PIAE.LangResources."+lang); 

     // resource not found, revert to default resource 
     if (null == stream) 
     {                 
      stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PIAE.Properties.LangResources.resources"); 
     } 

     ResourceReader reader = new ResourceReader(stream); 
     IDictionaryEnumerator en= reader.GetEnumerator(); 
     while (en.MoveNext()) 
     { 
      if (en.Key.Equals(str)) 
      { 
       return en.Value.ToString(); 
      } 
     } 

     // string not translated, revert to default resource 
     return LangResources.ResourceManager.GetString(str); 
    } 
+6

+1, usiamo un approccio simile. Fa male che .net ti costringe a reinventare la ruota se si desidera evitare assemblee satellitari. Una pessima decisione di progettazione, IMO. – Heinzi

+0

Bel approccio.Volevo solo aggiungere che un 'ResourceSet' può essere usato attorno al lettore, per facilitare il recupero dei valori per nome. –

4

Non l'hai trovato perché non è il modo in cui funziona .NET framework. .NET si aspetta che le DLL satellite si trovino in una posizione specificatamente denominata (directory iow denominate in base alla lingua delle risorse in esse contenute, ad esempio de, , chs, ...). Se non si lavora in questo modo, .NET non sarà in grado di applicare la sua magia (che è quella di selezionare automaticamente la risorsa corretta in base alla cultura dell'interfaccia utente corrente: Thread.CurrentThread.CurrentUICulture).

+2

Va bene per me, posso trasmettere la cultura corretta da solo - ma distribuisco un piccolo strumento e sicuramente non voglio aggiungere alcun sottodir/DLL. Solo un EXE, anche se il framework .NET offre un piccolo aiuto qui. – tomash

0

Utilizzare questo programma, lavora con me: EXEPack

Hai solo bisogno di fare manualmente ogni volta che si compila, non so se ci sia uno strumento di comando.

Problemi correlati