janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Localisation d'un script en plusieurs langues - 16/01/09 18:26
Hello,
Pour info, je viens de mettre en ligne un nouveau billet sur mon blog, traitant de la fonctionnalité de "script internationalization" disponible dans la v2 CTP3.
http://janel.spaces.live.com/blog/cns!9B5AA3F6FA0088C2!416.entry
Cette fonctionnalité permet de fournir automatiquement des messages adaptés à la langue de l'utilisateur (attention: la traduction n'est pas automatique, c'est la sélection de la langue selon le contexte qui l'est ).
N'hésitez pas à laisser un commentaire sur mon blog ou à répondre à ce fil si vous avez des remarques ou des questions.
Janel
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 10:38
Sur le même sujet mais concernant la localisation des messages d'erreur de PS, voir ce script (Get-PSResourceString). Pour la V1 il reste possible de mettre en place un système de localisation basé sur un fichier de ressource et des hashtables. Cela demande un peu plus de code mais n'est pas vraiment pour débutant
Sinon cette section Data est bien indépendante de la notion de "script-Module" ? On peut l'utiliser dans un module pour découpler le code des données ? Enfin si toutefois tu as testé cet aspect, de mon coté je n'ai pas encore pris le temps de creuser le sujet
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 11:27
Fichtre, les exemples que tu fournis sont très intéressants mais en effet, ils sont très complexes à mettre en oeuvre.
Pour faire de la localisation avec la v1, j'aurais simplement pensé reprendre le principe utilisé dans la commandelette import-localizeddata de la v2, dont la difficulté technique essentielle réside dans la richesse potentielle du contenu des fichiers .psd1.
Or, dans 99% des cas de localisation on a simplement besoin d'énumérer des chaînes dans des hashtables (clé = nom de la variable, valeur = contenu de la variable), et pour ça il n'y a pas besoin de faire des choses très complexes. Il suffit de pointer sur le bon fichier en fonction de la culture, et de charger les couples clé/valeur dans le fichier en question. Si j'ai un peu de temps dans la journée j'écrirai une fonction que je publierai ici pour que vous regardiez si ça pourrait convenir.
Quant aux scripts/modules, oui c'est une notion totalement différente. Et à priori oui, on peut utiliser une section Data dans un module. Un module peut contenir scripts et DLL selon les besoins, donc pourquoi pas des sections Data et des sous-répertoires localisés. Mais moi non plus je n'ai pas testé.
Janel
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 13:02
Bon, voici une version simplissime au possible:
| Code: |
function import-localizeddata
{
param (
[string]$filename = [IO.Path]::GetFileNameWithoutExtension((split-path -leaf $myinvocation.MyCommand)),
[System.Globalization.CultureInfo]$UIculture = (get-UIculture)
)
$fullpath = $(split-path $myinvocation.ScriptName) + "\$UIculture\$filename" + ".psl1"
$ht = @{}
get-content $fullpath | where {($_.TrimStart()) -ne "" -and ($_.TrimStart())[0] -ne "#"} | foreach {
$key, $value = $_.Split("=", 2)
$ht.Add($key.Trim(), $value.TrimStart())
}
$ht
}
|
La fonction ci-dessus permet d'importer des données selon la culture de la session en cours ou en précisant une culture particulière. Evidemment (c'était le but de l'exercice) ça marche avec la v1 de PowerShell.
Chaque fichier de données doit être placé dans un répertoire portant le nom de la culture ("fr-FR", "en-US", etc). Ce répertoire lui-même doit être placé dans le même répertoire que le script.
Par défaut, le fichier lu aura le même nom que le script, avec une extension différente: .psl1 (pour PowerShell Localization, v1 ). Mais on peut préciser un autre nom de fichier. Attention à ne pas préciser l'extension, elle est rajoutée par la fonction!
Enfin, le contenu d'un fichier doit être sous la forme suivante:
<nom> = <valeur>
Pour faciliter la lecture du fichier, on peut ajouter des lignes vierges et des lignes de commentaire commençant par #.
Contrairement à la commandelette import-localizeddata de la v2, je ne passe pas le nom de la variable en paramètre. Ici, le contenu est retourné par la fonction sous la forme d'une hashtable qu'il revient à l'utilisateur de traiter comme il l'entend. A priori on affectera le résultat de la fonction à une variable.
Prenons un exemple. Dans mon répertoire c:/tests j'ai un script test-local.ps1 et deux répertoires, c:/tests/en-US et c:/tests/fr-FR. Chacun de ces deux répertoires contient un fichier test-local.psl1.
| Code: |
PS> get-content c:\tests\fr-FR\test-local.psl1
# culture "fr-FR"
Welcome = Bienvenue au jeu "Devinez un jour" !
Prompt = Tapez un nom de jour
Success = Vous avez deviné ! Toutes nos félicitations !
PS> get-content c:\tests\en-US\test-local.psl1
# culture "en-US"
Welcome = Welcome to the "Guess a day" game!
Prompt = Enter the name of any day
Success = You had it right! Congratulations!
|
Dans le deuxième fichier j'ai ajouté des espaces pour montrer qu'on peut en ajouter en début de ligne sans qu'ils interfèrent dans la lecture du fichier.
Voyons maintenant le script test-local.ps1 :
| Code: |
PS> get-content c:\tests\test-local.ps1
param ([System.Globalization.CultureInfo]$myculture = (get-UIculture))
. c:\scripts\import-localizeddata.ps1
$messages = import-localizeddata -uiculture $myculture
$messages.Welcome
$messages.Prompt
$messages.Success
|
Pour l'exercice, j'ai également sauvegardé la fonction import-localizeddata dans un fichier import-localizeddata.ps1, dans un répertoire c:/scripts. J'importe la fonction en début d'exécution de mon script, grâce à la technique de "dot-sourcing".
Enfin, voyons deux exemples d'usage du script :
| Code: |
PS> .\test-local
Bienvenue au jeu "Devinez un jour" !
Tapez un nom de jour
Vous avez deviné ! Toutes nos félicitations !
PS> .\test-local en-US
Welcome to the "Guess a day" game!
Enter the name of any day
You had it right! Congratulations!
|
Voilà. On peut perfectionner la fonction pour qu'elle lise un tableau plus complexe, permettant par exemple d'ajouter des dimensions supplémentaires si on veut regrouper plusieurs tables de messages dans un même fichier. Mais en l'état ça me semble déjà couvrir 90% des besoins de localisation.
Commentaires bienvenus. Je posterai tout ça sur mon blog dans la journée.
Janel
Message édité par: janel, à: 20/01/09 13:07
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 14:43
janel écrit:
Or, dans 99% des cas de localisation on a simplement besoin d'énumérer des chaînes dans des hashtables (clé = nom de la variable, valeur = contenu de la variable), et pour ça il n'y a pas besoin de faire des choses très complexes.
Dans mons cas l'objectif d'origine était d'automatiser la génération de fichier ressources, et une fois terminé je me suis dit que cela pouvait éventuellement servir à une localisation. Ta solution est bien mieux adaptée car l'objectif est clairement établi. En tout cas,et comme on dit au billard, belle bille !
Peut-être qu'un Select-string + une regex serait plus adapté pour, mais je n'ai pas testé :
get-content $fullpath | where ...
Et proposer un switch pour gérer ou non les espaces, ainsi on peut récupérer le texte brut.
janel écrit: mais en effet, ils sont très complexes à mettre en oeuvre.
Tu peux préciser ?
Message édité par: Laurent Dardenne, à: 20/01/09 14:44
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 15:17
Laurent Dardenne écrit:
Peut-être qu'un Select-string + une regex serait plus adapté pour, mais je n'ai pas testé
Peut-être, ça ne m'est pas venu à l'esprit. Je suis allé au plus simple, et en général je n'utilise les regex que lorsque je ne vois pas de solution simple en recherche littérale. Or, ici get-content, un simple filtrage et un Split("=",2) faisaient l'affaire! 
Et proposer un switch pour gérer ou non les espaces, ainsi on peut récupérer le texte brut.
Hmmm, pourquoi pas, mais peux-tu préciser dans quel cas ça te serait utile?
janel écrit: mais en effet, ils sont très complexes à mettre en oeuvre.
Tu peux préciser ?
Le principe des ressources basé sur les streams NTFS nécessite d'installer NTFS.DLL sur les postes. Egalement, le stockage des ressources dans ces streams est totalement invisible pour la plupart des programmes, ce qui peut provoquer des pertes de données si, par exemple, on fait un malencontreux copier/coller du fichier sans penser à récupérer ses streams. Enfin, il faut penser à toujours déposer un tel fichier sur une partition NTFS sous peine de voir tous ses streams disparaître à tout jamais.
A part ça, en testant ma fonction sur un poste équipé de la v2 j'ai constaté qu'elle ne marchait pas, à cause de la variable $myinvocation.ScriptName qui n'est pas renseignée dans la v2... Galère. Ma solution est donc propre à la v1, alors que j'aurais voulu qu'elle soit universelle. A creuser. Je publierai la version corrigée dès que possible.
Janel
Message édité par: janel, à: 20/01/09 15:18
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 15:52
janel écrit: Je suis allé au plus simple
Le mieux est l'ennemi du bien janel écrit:
Hmmm, pourquoi pas, mais peux-tu préciser dans quel cas ça te serait utile?
Je n'en ai pas vraiment en tête mais je me disais qu'il vallait mieux, encore lui, proposer le texte soit filtré soit sans filtrage. Et ainsi laisser l'utilisateur décider. janel écrit: Le principe des ressources basé sur les streams NTFS nécessite d'installer NTFS.DLL sur les postes.
Dans le tuto en question j'ai abordé les streams comme une possible solution de stockage de ressource mais ce que je proposais était basé sur un fichier de ressources .NET janel écrit:
ce qui peut provoquer des pertes de données si, par exemple, on fait un malencontreux copier/coller du fichier sans penser à récupérer ses streams.
Effectivement c'est pourquoi je n'utilise pas cette option.Et je ne l'ai peut être pas préciser dans le tuto . En passant, l'outil PrimalScript associe de nombreux streams à un script crée dans leur éditeur. janel écrit:
qui n'est pas renseignée dans la v2... Je suis en train de travailler +- sur le sujet sur la ctp3 :
| Code: |
function Get-Caller
{
(Get-Variable MyInvocation -Scope 1).Value
}
$C=Get-Caller
$C
# MyCommand : Main.ps1
# BoundParameters : {}
# UnboundArguments : {}
# ScriptLineNumber : 1
# OffsetInLine : 11
# ScriptName :
# Line : .\Main.ps1
# PositionMessage :
# At line:1 char:11
# + .\Main.ps1 <<<<
# InvocationName : .\Main.ps1
# PipelineLength : 1
# PipelinePosition : 1
# ExpectingInput : False
# CommandOrigin : Runspace
|
A l'origine c'est une solution proposée par J.Snoover.
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 16:15
Laurent Dardenne écrit: A l'origine c'est une solution proposée par J.Snoover. oups, cela ne règle rien.
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 16:47
Sous la v2 cela fonctionne en utilisant ceci :
| Code: |
$myinvocation.MyCommand.Definition
|
Et l'appel dans test-local doit être
| Code: | . .\import-localizeddata.ps1
|
Sinon l'appel se fait sur le cmdlet et pas sur la fonction.
Je n'ai pas testé sous la V1.
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Re:Localisation d'un script en plusieurs langues - 20/01/09 18:56
Oui, $myinvocation.mycommand.definition marche avec la CTP3 (ainsi que $myinvocation.mycommand.path), mais là c'est avec la v1 que ça ne marche plus...
Comme les fonctionnalités de la v1 sont censées être toujours supportées dans la v2, j'ai signalé le problème et un bug a été ouvert. A suivre...
En attendant, j'ai ajouté un test à ma fonction pour qu'elle puisse servir telle quelle sous les deux versions - au passage, je l'ai renommée en import-culturaldata pour éviter le conflit avec import-localizeddata sous la v2 :
| Code: |
function import-culturaldata
{
param (
[string]$filename = [IO.Path]::GetFileNameWithoutExtension((split-path -leaf $myinvocation.MyCommand)),
[System.Globalization.CultureInfo]$UIculture = (get-UIculture)
)
if ($myInvocation.ScriptName) { $scriptname = $myInvocation.ScriptName }
else { $scriptname = $myInvocation.MyCommand.Definition }
$fullpath = $(split-path $ScriptName) + "\$UIculture\$filename" + ".psl1"
$ht = @{}
get-content $fullpath | where {($_.TrimStart()) -ne "" -and ($_.TrimStart())[0] -ne "#"} | foreach {
$key, $value = $_.Split("=", 2)
$ht.Add($key.Trim(), $value.TrimStart())
}
$ht
}
|
Janel
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 1/02/09 19:25
Comme j'envisage de localiser qq scripts j'ai testé quelques formats de chaîne, par exemple ceux-ci:
| Code: |
Welcome_2 = {0} : {1}
Prompt_2 = $Prompt
Prompt2_2 = `$V2Prompt
Success_2 = `tSuccess`r`n
|
Pour le premier pas de soucis :
| Code: |
$messages.Welcome_2 -f "1","2"
#1 : 2
|
Pour l'avant-dernier un appel à ExpandString suffit :
| Code: |
$Prompt="Indirection"
$ExecutionContext.InvokeCommand.ExpandString($messages.Prompt_2)
#Indirection
|
Pour le dernier Success_2 je n'ai pas trouvé mieux que ceci pour récupèrer la chaîne attendue :
| Code: |
$S=&$ExecutionContext.InvokeCommand.NewScriptBlock("`$ExecutionContext.InvokeCommand.ExpandString(`"$($messages.Success_2)`")")
$S
# Success
#
|
Connais-tu une approche plus simple dans ce cas ?
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Re:Localisation d'un script en plusieurs langues - 2/02/09 09:28
La méthode ExpandString utilisée dans le 2e cas semble également marcher pour le 3e, en tout cas sur mon poste. Mais je n'ai testé que sur mon portable avec la CTP3, quelle version utilises-tu?
Janel
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 2/02/09 10:14
janel écrit: quelle version utilises-tu?
La V1 sous XP.
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Re:Localisation d'un script en plusieurs langues - 3/02/09 17:41
Je testerai ce soir, je te dirai si je vois une technique plus simple.
Janel
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 3/02/09 17:53
janel écrit: Je testerai ce soir, je te dirai si je vois une technique plus simple.
Merci. De mon coté j'ai trouvé une autre approche avec regex.Escape et Unescape, mais dans ce cas il faut utiliser les caractères d'échapement du C/C# :
Du coup soit je traite toutes les lignes ou je précise une convention pour les lignes à traiter, par exemple
| Code: | \Name=\tSuccess\r\n
|
Ce qui me gêne un peu
Et sur MS-Connect je n'ai pas trouvé de bug à ce sujet.
Message édité par: Laurent Dardenne, à: 3/02/09 17:56
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 10/02/09 18:27
Je me suis lancé dans la localisation du Wrapper Log4Net et il y a un cas de figure qui ne semble pas pris en charge. Si je ne livre pas que les répertoires des langues US et Fr et qu'un poste configuré en Allemand utilise ce script alors le répertoire du nom de langue récupéré n'existe pas. Pour éviter cette situation il est peut être préférable dans ce cas de préciser une langue par défaut, par exemple US. Ainsi les messages d'erreurs sont bien renseignés.
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Re:Localisation d'un script en plusieurs langues - 10/02/09 18:37
Bien vu. Je mettrai à jour le script pour intégrer ce cas de figure.
Merci !
Janel
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 11/02/09 15:43
Pour infos si on renseigne le nom de fichier de ressources, cela ne fonctionne pas:
| Code: |
$Global:messages = import-localizeddata "G:\PS\Log4NET\testlocal\fr-FR\PackageLog4Net.psl1" $myculture
|
J'utilise ce cas car j'ai un script d'initialisation InitializeLG4N.ps1 et ce script charge le script PackageLog4Net.ps1 qui lui est localisé.
Le parsing suivant du nom de fichier ne se fait pas :
| Code: | $FileName = [IO.Path]::GetFileNameWithoutExtension((split-path -Leaf $MyInvocation.MyCommand))
|
Au passage sous PS V1, l'appel suivant suffit :
| Code: | [IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand)
|
Donc si on déplace cette instruction dans le corps du script pour tester les 2 cas, alors il faut interroger le scope de l'appelant :
| Code: |
write-host "FileName : $FileName" -fore green
$ParentInvocation = (Get-Variable MyInvocation -Scope 1).Value
write-host "Invoke $($ParentInvocation.MyCommand)" -fore green
if ($FileName -eq [String]::Empty)
{ $FileName=$ParentInvocation.MyCommand }
$FileName= [IO.Path]::GetFileNameWithoutExtension($FileName)
write-host "FileName : $FileName" -fore green
|
De mon coté, pour faciliter la distinction des noms de fichiers j'ai renommé en DataFileName et CallerScriptName.
Une dernière, si une des ligne ne respecte pas la structure ChaîneClé=ChaîneContenu, par exemple ;test alors le script part en erreur, normal. Mais dans ce cas on a un peu de mal à savoir ce qui se passe.
Cas d'erreur :
;todo
=
A=
=B
t=#dir#
C#=Language
#tests pour unescape
K1=tTabulation
K2=tTabulation
K3=Tabulationx
K4=Tabulationz
K5=c:testfichier.txt
K6="c:testfichier.txt"
#Seul le nom de fichier suivant est pris en compte sans erreur
K7="c:testfichier.txt" #ce commentaire est inclus dans la valeur de la clé
tK1=Tab
J'ai ajouté le contrôle suivant, pour les exceptions levées par $Ht.Add et $Value=[Regex]::Unescape :
| Code: |
...
Foreach {
trap [System.ArgumentException] {Write-error "$key=$value`r`n$($_.Exception.Message)";Continue}
...
|
Ensuite pour la chaîne d'origine suivante :
| Code: | Throw "Add-LogAppender : le paramètre Logger n'implémente pas l'interface ILoggerWrapper."
|
je déclare la chaîne :
NotImplementInterface={0} : le paramètre {1} n'implémente pas l'interface {2}.
sa construction se fait par l'appel suivant :
| Code: |
throw $messages.NotImplementInterface -F "Add-LogAppender","Logger","ILoggerWrapper"
|
Rien d'extraordinaire donc.
Si on souhaite effectuer d'autres traitements par exemple un expandstring, on peut créer une méthode sur la hashtable au lieu de créer des routines annexes (je suppose une seule hashtable de localisation par script):
| Code: |
$messages=$messages|add-member ScriptMethod Get {
#Args[0] contient par convention la clé de la Hashtable
# -F recoit un tableau de string
$this.Item($Args[0]) -F $Args[1..($Args.Count-1)]
# Exemple pour : NullParameter={0} : le paramètre {1} est à null.
# $Datas.Get("NullParameter","Getlogger", "Logger")
#Si on passe à la fonction formatage plus de paramètres que nécessaire cela ne pose pas de pb
} -pass
$messages=$messages|add-member ScriptMethod ExpandString{
$ExecutionContext.InvokeCommand.ExpandString($this.Item($Args[0]) )
} -pass
#$messages=$messages|add-member ScriptMethod UnEscape, etc
#Appels
throw $messages.Get("NotImplementInterface","Add-LogAppender","Logger","ILoggerWrapper")
throw $messages.ExpandString("FileError")
|
Il reste, je pense, un cas à étudier : J'utilise la culture par défaut US mais sur un poste configuré par exemple en cyrillique, en arabe ou en japonais.
Dans ce cas je ne sais pas ce que donnera l'affichage, j'ai donc relu ce post. A ton avis pour le tester l'installation d'une de ces pages de code suffit ?
Message édité par: Laurent Dardenne, à: 11/02/09 15:46
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 16/02/09 16:28
Pour les postes Windows non-latin, je pense me baser sur ce code :
| Code: |
#Détermine si une chaîne de caractère unicode, contenant la date du jour, est dans une page de code
latine
$Datas=$Datas|add-member NoteProperty IsBasicLatin ((get-date -uf %A) -match "\p{IsBasicLatin}" ) -pass
#Détermine si le fichier de données est celui par défaut
$Datas=$Datas|add-member NoteProperty IsDefaultCulture ($isDefaultCulture) -pass
$Datas=$Datas|add-member ScriptMethod Get {
#Args[0] contient par convention la clé de la Hashtable
# -F recoit un tableau de string
$Text=$this.Item($Args[0]) -F $Args[1..($Args.Count-1)]
# Exemple pour l'entrée : NullParameter={0} : le paramètre {1} est à null.
# $Datas.Get("NullParameter","Getlogger", "Logger")
#Si on passe à la fonction de formatage plus de paramètres que nécessaire cela ne pose pas
de problème
#La culture par défaut n'est pas latine, on formate le message avec la culture invariante.
#"La propriété CultureInfo.InvariantCulture n'est ni une culture neutre, ni une culture
spécifique.
#Cette culture d'un troisième type pourrait être qualifiée d'indifférente.
#En effet, la culture invariante est associée à la langue anglaise, mais non à un pays ou à
une région".
if ( ($this.IsDefaultCulture) -and ($this.IsBasicLatin -eq $false) )
{ [String]::Format($Text, [System.Globalization.CultureInfo]::InvariantCulture) }
} -pass
|
Reste à vérifier la pertinence de cet ajout...
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
janel
Utilisateur
 PowerShelleur Platinum
| Messages: 362 |   | Karma: 13
|
Re:Localisation d'un script en plusieurs langues - 16/02/09 17:40
Hello Laurent,
Désolé pour le manque de suivi sur ce fil. Merci en tout cas pour l'intérêt porté à ce modeste bout de script.
Quant à tes (nombreuses ) questions, il faudra que je regarde ça dans les prochains jours. Je reviendrai poster mes observations et mes modifs le cas échéant.
Janel
|
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 16/02/09 18:33
janel écrit: Merci en tout cas pour l'intérêt porté à ce modeste bout de script.
Il est peut être modeste mais répond à un vrai besoin, les choses simples sont souvent les plus utiles, de plus on trouve peu d'info sur la localisation de script en V1. Je continue de creuser le sujet; En regardant ce blog, du traducteur chinois de PowerGUI, on peut voir que l'affichage de l'alphabet latin ne semble pas poser de pb dans une console PowerShell localisée, enfin si toutefois elle l'est vraiment et n'est pas une console US avec le langage chinois. Si les mots-clé du langage PS ne sont pas localisés, comment signifier Get-Item en chinois , l'usage de la culture invariant répondra parfaitement je pense. En attendant je vais consulter ces infos sur la globalisation/localisation d'application.
Comme je vais placer sur CodePlex les scripts du wrapper PS pour Log4Net, j'aurais peut être un retour sur ce point. Du coup j'ajoute ton script original et celui à ma sauce dans la distribution de ce projet. Et enfin si j'ai le temps je tenterais d'installer une version non-latine de Windows sous virtualPC...
Message édité par: Laurent Dardenne, à: 16/02/09 18:33
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 17/02/09 15:49
Après pas mal de recherche, je suis tombé sur ceci mais pour la console cmd.exe:
This behavior is by design. Arabic and Hebrew (and for that matter Thai, Hindi, and other complex scripts) are not supported on Windows 2000 and Windows XP console.
Je pense que pour utiliser ces langues sur une version Fr la question est réglée. Ensuite pour l'affichage dans la console du grec ou du cyrillique on utilisera la fonction de test suivante :
| Code: |
# Windows PowerShell Cookbook
# http://my.safaribooksonline.com/9780596528492/program_invoke_a_script_block_with_alter?
portal=oreilly
function Set-Culture(
[System.Globalization.CultureInfo] $culture =
$(throw "Please specify a culture"),
[ScriptBlock] $script = $(throw "Please specify a scriptblock")
)
{
## A helper function to set the current culture
function SetCulture([System.Globalization.CultureInfo] $culture)
{
[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture
[System.Threading.Thread]::CurrentThread.CurrentCulture = $culture
}
## Remember the original culture information
$oldCulture = [System.Threading.Thread]::CurrentThread.CurrentUICulture
## Restore the original culture information if
## the user's script encounters errors.
trap { SetCulture $oldCulture }
## Set the current culture to the user's provided
## culture.
SetCulture $culture
## Invoke the user's scriptblock
& $script
## Restore the original culture information.
SetCulture $oldCulture
}
|
Si on affiche la date en grec ou en russe, l'affichage est erroné :
| Code: |
Set-Culture el-GR {get-date;(get-date).ToString("U", [System.Globalization.CultureInfo]::InvariantCulture)}
#???t?, 17 Feß???a???? 2009 3:06:33 µµ
#Tuesday, 17 February 2009 14:06:33
Set-Culture ru-RU {get-date;(get-date).ToString("U", [System.Globalization.CultureInfo]::InvariantCulture)}
#17 ??????? 2009 ?. 15:07:00
#Tuesday, 17 February 2009 14:07:00
|
En modifiant la police de la fenêtre de PS en "Lucida Console", le résultat est correct.
On peut visualiser les caractères de cette police par exemple sous Word, menu "Insertion-Caractères spéciaux", onglet Symbole, listbox "Police" et "Sous-ensemble".
En utilisant la listbox "Sous-ensemble" on voit que les polices Windows telles que Arial contiennent l'Arabe, l'hébreu, etc, mais que la police Lucida ne contient pas ces sous-ensembles.
| Code: |
#Sous Joomla l'affichage du russe et du grec ne passe pas...
Set-Culture en-US {get-date;(get-date).ToString("U", [System.Globalization.CultureInfo]::InvariantCulture)}
#Tuesday, February 17, 2009 3:08:27 PM
#Tuesday, 17 February 2009 14:08:27
get-date
#mardi 17 février 2009 15:08:28
|
Pour le dernier on voit que la date affichée avec l'invariant ne respecte pas l'heure d'hiver mais la première semble respecter le fuseau horaire.
Sinon la syntaxe suivante ne renvoie pas la date au format invariant :
| Code: |
Set-Culture el-gr {get-date;[String]::Format("{0:F}",$(get-date), [System.Globalization.CultureInfo]::InvariantCulture)}
|
Donc pour d'autres tests je dois installer, je pense, un Windows US MUI + les packages des langues à tester, et PS US + les packages MUI...
Message édité par: Laurent Dardenne, à: 17/02/09 15:55
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
Laurent Dardenne
Utilisateur
 PowerShelleur Platinum
| Messages: 1406 |  | Karma: 44
|
Re:Localisation d'un script en plusieurs langues - 17/02/09 17:59
Pour le dernier test, il faut inverser les paramètres :
| Code: | Set-Culture el-GR {get-date;[String]::Format([System.Globalization.CultureInfo]::InvariantCult
ure,"{0:F}",(get-date))}
|
Une maille à l'endroit, une maille à l'envers
Tutoriels PowerShell -- Liste de ressources autour de PowerShell |
|
|
| | L'administrateur a désactivé l'accés public en écriture. |
|