Valószínű ez a téma már csak olyan PowerShell szkriptereket érint, akik nem csak saját munkájuk megkönnyítésére készítenek szkripteket, hanem szélesebb körben felhasználható okosságokat készítenek, akár egy multinacionális cég keretein belül, vagy akár a nagyközönség számára egy „termék” formájában.
Ilyen körben érdekes lehet, hogy a szkriptünk mindenkinek a saját nyelvén szóljon. Ennek feltétele egyrészt az, hogy információt szerezzünk a nyelvi környezetről, amiben a számítógép és azon belül a szkript fut. Ezt megkönnyítendő van néhány cmdletünk. Az első a Get-Culture , ami a gép területi beállításából (és nem a felhasználói felület nyelvéből) fakadó nyelv-specifikus jellemzőit adja vissza:
[26] PS C:\munka> get-culture | fl *
Parent : hu
LCID : 1038
KeyboardLayoutId : 1038
Name : hu-HU
IetfLanguageTag : hu-HU
DisplayName : Hungarian (Hungary)
NativeName : magyar (Magyarország)
EnglishName : Hungarian (Hungary)
TwoLetterISOLanguageName : hu
ThreeLetterISOLanguageName : hun
ThreeLetterWindowsLanguageName : HUN
CompareInfo : CompareInfo - 1038
TextInfo : TextInfo - 1038
IsNeutralCulture : False
CultureTypes : SpecificCultures, InstalledWin32Cultures, Fra
meworkCultures
NumberFormat : System.Globalization.NumberFormatInfo
DateTimeFormat : System.Globalization.DateTimeFormatInfo
Calendar : System.Globalization.GregorianCalendar
OptionalCalendars : {System.Globalization.GregorianCalendar}
UseUserOverride : True
IsReadOnly : False
Ez tehát nem magának a Windowsnak a nyelve, hanem a területi beállításból fakadó nyelv. Az én gépem például angol, de a területi beállítás magyar.
A kimenet egy összetett objektum, aminek tulajdonságai is összetettek, így érdemes mélyebbre ásni. Nézzük például a dátum és idő formátumának jellemzőit:
[28] PS C:\munka> (get-culture).datetimeformat
AMDesignator : de.
Calendar : System.Globalization.GregorianCalendar
DateSeparator : .
FirstDayOfWeek : Monday
CalendarWeekRule : FirstDay
FullDateTimePattern : yyyy. MMMM d. H:mm:ss
LongDatePattern : yyyy. MMMM d.
LongTimePattern : H:mm:ss
MonthDayPattern : MMMM d.
PMDesignator : du.
RFC1123Pattern : ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ShortDatePattern : yyyy. MM. dd.
ShortTimePattern : H:mm
SortableDateTimePattern : yyyy'-'MM'-'dd'T'HH':'mm':'ss
TimeSeparator : :
UniversalSortableDateTimePattern : yyyy'-'MM'-'dd HH':'mm':'ss'Z'
YearMonthPattern : yyyy. MMMM
AbbreviatedDayNames : {V, H, K, Sze...}
ShortestDayNames : {V, H, K, Sze...}
DayNames : {vasárnap, hétfő, kedd, szerda...}
AbbreviatedMonthNames : {jan., febr., márc., ápr....}
MonthNames : {január, február, március, április...}
IsReadOnly : False
NativeCalendarName : Gergely-naptár
AbbreviatedMonthGenitiveNames : {jan., febr., márc., ápr....}
MonthGenitiveNames : {január, február, március, április...}
Innen ki lehet nyerni akár a napok, vagy a hónapok neveit, látható az adott nyelvi környezetben megszokott dátum- és időformátum.
Hasonló kimenetet generál a Get-UICulture cmdlet is, azonban ez a Windows nyelve alapján adja meg az adatokat, az én gépem esetében az angolt:
[27] PS C:\munka> get-uiculture | fl *
Parent : en
LCID : 1033
KeyboardLayoutId : 1033
Name : en-US
IetfLanguageTag : en-US
DisplayName : English (United States)
NativeName : English (United States)
EnglishName : English (United States)
TwoLetterISOLanguageName : en
ThreeLetterISOLanguageName : eng
ThreeLetterWindowsLanguageName : ENU
CompareInfo : CompareInfo - 1033
TextInfo : TextInfo - 1033
IsNeutralCulture : False
CultureTypes : SpecificCultures, InstalledWin32Cultures, Fra
meworkCultures
NumberFormat : System.Globalization.NumberFormatInfo
DateTimeFormat : System.Globalization.DateTimeFormatInfo
Calendar : System.Globalization.GregorianCalendar
OptionalCalendars : {System.Globalization.GregorianCalendar, Syst
em.Globalization.GregorianCalendar}
UseUserOverride : True
IsReadOnly : False
Ennek felhasználásával nézzük, hogyan lehet mondjuk a dátumokat nem a területi beállítás szerint, hanem a Windows nyelve szerint megjeleníteni:
PS C:\> get-date -Format (Get-UICulture).datetimeformat.fulldatetimepattern
kedd, február 23, 2010 12:53:28 du.
Ez csak részben sikerült sajnos. A szerkezet angolos, de a részletekben már a magyar nyelv előtört. Szerencsére az objektumoknál megtalálható ToString metódus rendelkezik nyelvi beállítás paraméterrel:
PS C:\> (get-date).ToString("dddd",(Get-UICulture))
Tuesday
Ennek alapján készítettem egy függvényt, ami már teljes egészében korrektül jeleníti meg a dátumokat:
function get-dateUICulture {
param(
[string] $format,
[datetime] $datetime = (get-date),
[object] $cultureinfo
)
if($cultureinfo -is [string]){
$cultureinfo =
New-Object system.globalization.cultureinfo $cultureinfo
}
elseif($cultureinfo -isnot [System.Globalization.CultureInfo]){
$cultureinfo = Get-UICulture
}
$datetime.tostring(
$(if($format){$cultureinfo.datetimeformat.$format}),
$cultureinfo)
}
A függvénynek három paraméter adható:
-Format: a (get-culture).datetimeformat alatt található különböző formátum-elnevezések
-DateTime: mit szeretnénk fordítani, ha nem adunk meg értéket, akkor az aktuális dátum
-CultureInfo: milyen nyelvnek megfelelő időformátumot kérünk, alaphelyzetben a UICulture-nek megfelelő nyelvet veszi alapul.
Nézzünk pár futtatási példát:
PS C:\> get-dateUICulture -format fulldatetimepattern -cultureinfo "hu-hu"
2010. február 23. 13:07:47
PS C:\> get-dateUICulture -format fulldatetimepattern
Tuesday, February 23, 2010 1:07:52 PM
PS C:\> get-dateUICulture -format fulldatetimepattern -cultureinfo "ar-SA"
09/ربيع الأول/1431 01:07:59 م
PS
C:\> get-dateUICulture -format fulldatetimepattern -cultureinfo
"ur-PK"
23
فرورى, 2010 2:17:42 PM
PS
C:\> get-dateUICulture -format fulldatetimepattern -cultureinfo
"th-TH"
23 กุมภาพันธ์ 2553
14:17:53
PS
C:\> get-dateUICulture -format fulldatetimepattern -cultureinfo
"zh-SG"
星期二, 23 二月, 2010 PM 2:18:23
A másik problémakör a nemzetközi szkriptekkel kapcsolatban a felhasználóknak szóló üzenetek különböző nyelvi változatainak kezelése. Erre a PowerShell 2.0-ban létrehoztak egy speciális adatszekciót a szkripteken belül, illetve speciális adatfájlok kezelésének lehetőségét. Az adatszekciót DATA kulcsszóval kell jelezni, és utána egy szkriptblokkba kell elhelyezni az adatokat, vagy szkriptet. Ebben a szkriptblokkban erősen leszűkített lehetőségekkel állunk szemben, gyakorlatilag alaphelyzetben sztringeket és csak egy cmdletet, a ConvertFrom-StringData-t tudjuk használni, de ez erre a feladatra pont elég. Az adatfájlok PSD1 kiterjesztésűek, és a főszkript melletti nyelvi kódnak megfelelő alkönyvtárban kell elhelyezni ugyanolyan név előtaggal, mint magát a szkriptet.
Ha szerepeltetjük a főszkriptünkben az Import-LocalizedData cmdletet, akkor az automatikusan az ő –UICulture paramétereként megadott nyelvi környezetnek megfelelő alkönyvtárt keresi, és onnan tölti fel a –bindingVariable-nek megadott változót. Érdemes itt az –ErrorAction hibakezelési paraméternek SilentlyContinue-t adni, mert különben, ha nem találja a megadott nyelvnek megfelelő alkönyvtárt, akkor csúnya hibát jelez. Ilyenkor amúgy nem nyúl a változóhoz, azaz a korábban definiált DATA szekció jut érvényre.
Hogyan épül ez az egész fel? Az alábbiakban látható a fő szkript. Ez a DATA szekcióban tartalmazza a felhasználóknak szóló alaphelyzet szerinti magyar üzeneteket. A szkript international.ps1 néven van elmentve, és nem túl sok izgalmasat csinál: kiírja a $Messages hashtábla Start kulcsában tárolt üzenetét, majd azt, hogy „Futás”, majd ugyanennek a hashtáblának az End kulcsában tárolt üzenetét.
$Messages = DATA {
ConvertFrom-StringData @'
# Alaphelyzet szerinti magyar szövegek
Start = A szkript éppen indul.
End = A szkript leállt.
'@ }
Import-LocalizedData -bindingVariable Messages -UICulture $PSCulture `
-ErrorAction SilentlyContinue
$Messages.Start
Write-Host "----
Futás -----"
$Messages.End
Van ugyanakkor a szkript mellett egy „en-us” alkönyvtár is, benne az international.psd1 adatfájl is:
PS C:\powershell2\v2\munka> dir .\en-us
Directory: C:\powershell2\v2\munka\en-us
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2010.02.22. 23:19 230 international.psd1
Ennek a tartalma a következő:
ConvertFrom-StringData @'
# English strings
Start =
The script has just started.
End = The
script ended.
'@
Láthatjuk, hogy hasonló a tartalma, mint a szkript DATA szekciójának, csak éppen más nyelven vannak a szövegek. Nézzük akkor, hogy hogyan fut a szkript alaphelyzetben:
PS C:\powershell2\v2\munka> .\international.ps1
A szkript éppen indul.
---- Futás -----
A szkript leállt.
Ha átállítom a területi beállításokat angolra, akkor ugyanez a szkript már másképp szól hozzánk:
PS C:\powershell2\v2\munka> .\international.ps1
The script has just started.
---- Futás -----
The script ended.
Ezekkel a lehetőségekkel tehát olyan szkripteket tudunk készíteni, amelyek egy többnemzetiségű környezetben is érthetően és elegánsan működnek.