Ennél „profibb” objektumtípusokat is létre tudunk hozni az Add-Type cmdlet segítségével. Az alábbiakban látható egy többsoros sztringként egy C# kódú osztálydefiníció:
$code = @"
public class email {
public string alias {get; set;}
public string domain {get; set;}
public email (string a, string d)
{
alias = a; domain = d;
}
public string fullemail
{
get { return alias + "@" + domain; }
}
public static string create (string alias, string domain)
{
return alias + "@" + domain;
}
}
"@
A fenti kód egy email adattípust hoz létre, egy publikus alias és domain adatmezővel, melyeket lekérdezni és beállítani is lehet. Van még egy fullemail tulajdonsága is, melyet csak lekérdezni lehet, hiszen ez az alias és a domain tulajdonságból generálódik. Van még egy konstruktora is email néven, melynek mind az alias, mind a domain paramétert meg kell adni. Van még egy create statikus metódusa is, amellyel email objektum létrehozása nélkül tudunk e-mail címet létrehozni. Nézzük, hogy hogyan tudunk ebből PowerShellben is használható típust generálni?
Add-Type -TypeDefinition $code -Language CSharpVersion3
Ezzel létre is jött a saját típusom. Most létre is hozok ebből egy objektumot, amit le is kérdezek:
[93] PS C:\munka> $address = New-Object email soost, iqjb.hu
[94] PS C:\munka> $address
alias domain fullemail
----- ------ ---------
soost iqjb.hu soost@iqjb.hu
Nézzük meg ennek az objektumnak a tulajdonságait is:
[95] PS C:\munka> $address | gm
TypeName: email
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
alias Property System.String alias {get;set;}
domain Property System.String domain {get;set;}
fullemail Property System.String fullemail {get;}
Látható, hogy ennek tagjellemzői tényleg úgy néznek ki, mint az „igazi” .NET-es típusoké. Az általam létrehozott tulajdonságok mellett az objektum mivoltából következő alap metódusok is megtalálhatók.
Ha megnézzük a statikus tagjellemzőket is, akkor láthatjuk a create metódusunkat is:
[96] PS C:\munka> [email] | Get-Member -Static
TypeName: email
Name MemberType Definition
---- ---------- ----------
create Method static string create(string alias, string domain)
Equals Method static bool Equals(System.Object objA, System.Ob...
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, ...
Ez a lehetőség igazán azok számára jelent nagy könnyebbséget, akik amúgy is rendelkeznek valamely .NET programnyelvben létrehozott osztálydefiníciókkal, így azokat nem csak a Visual Studio projektjeikben tudják felhasználni, hanem közvetlenül PowerShellből is.
Megjegyzés
Van egy „nem hivatalos”, de praktikus módja egyedi objektumok létrehozásának:
[46] PS C:\> $ember="" | Select-Object -Property Név, Életkor, Lábméret
[47] PS C:\> $ember.név="Soós Tibor"
[48] PS C:\> $ember.Életkor = 39
[49] PS C:\> $ember.Lábméret = 38
[50] PS C:\> $ember
Név Életkor Lábméret
--- ------- --------
Soós Tibor 39 38
[51] PS C:\> $ember | Get-Member
TypeName: Selected.System.String
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Lábméret NoteProperty System.Int32 Lábméret=38
Név NoteProperty System.String Név=Soós Tibor
Életkor NoteProperty System.Int32 Életkor=39
Definiálok egy bármilyen, nem $null-t tartalmazó változót, és tovább tolom a Select-Object cmdletnek, és kiválasztok olyan tulajdonságokat, amelyek nincsenek is az eredeti objektumban. Ezután ez az objektum „Selected” altípusa lesz az eredeti objektumtípusnak, jelen esetben Selected.System.String típus lett. Ez el is veszítette az eredeti tulajdonságait, helyette az általam kiválasztottakkal rendelkezik, melyeknek értéket is lehet adni.
Másik, még gyakran előforduló igény, hogy egy változó csak bizonyos értékeket vehessen fel, például csak a hét napjai kerülhessenek bele. Ha ez a változó egy függvény paramétere, akkor erre majd látni fogjuk a validációs attribútumok lehetőségét a 2.5.3.1 Ellenőrzési szabályok rendelése változókhoz fejezetben. De van más lehetőségünk is, ez pedig a .NET háttérnek köszönhető, azon belül is az enum típusnak:
[1] PS C:\> $napok = "hétfő, kedd, szerda, csütörtök, péntek, szombat, vasárnap
"
[2] PS C:\> Add-Type –TypeDefinition "public enum Napok {$napok}"
A fenti két sorral létrehoztam egy új típust, ami Napok névre hallgat, és amely csak a hét napjait veheti fel értéknek.
Megjegyzés
Fontos, hogy itt a „public” és az „enum” szavak kisbetűsek! Ez nem a PowerShellnek köszönhető, hanem a C# nyelvnek, amit itt tulajdonképpen használtunk.
Hogyan tudjuk ezt használni? Nézzünk erre példákat:
[8] PS C:\> $nap = [napok] "hétfő"
[9] PS C:\> $nap
hétfő
[10] PS C:\> $nap | Get-Member
TypeName: Napok
Name MemberType Definition
---- ---------- ----------
CompareTo Method int CompareTo(System.Object target)
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
GetTypeCode Method System.TypeCode GetTypeCode()
ToString Method string ToString(), string ToString(string format, Sy...
value__ Property System.Int32 value__ {get;set;}
[11] PS C:\> $másiknap = [napok] "blabla"
Cannot convert value "blabla" to type
"Napok" due to invalid enumeration value
s. Specify one of the following enumeration values
and try again. The possible
enumeration
values are "hétfő, kedd, szerda, csütörtök, péntek, szombat, vasá
rnap".
At line:1 char:20
+ $másiknap = [napok] <<<< "blabla"
+
CategoryInfo : NotSpecified: (:)
[], RuntimeException
+
FullyQualifiedErrorId : RuntimeException
A [8]-as sorban a $nap változónak adtam egy értéket a lehetséges napok közül. Ez hiba nélkül lement, még a tagjellemzők is látszanak a [10]-es sor kimeneteként.
Ezzel szemben, ha a $másiknap változónak olyan napot próbálok adni, ami nincs a listában, akkor hibajelzést kapunk.
Természetesen ezzel a [napok] típussal már valójában nem sztringgel dolgozunk, így a sztringekre jellemző metódusokról és tulajdonságokról is le kell mondanunk. (Valamit valamiért.) Viszont könnyen lehet sztringgé konvertálni:
[14] PS C:\> ([string] $nap).length
5
[15] PS C:\> ([string] $nap).toupper()
HÉTFŐ
Azaz itt is nagy a szabadságunk arra vonatkozólag, hogy egy problémát milyen módszerrel oldunk meg.
Az Add-Type segítségével hozzáadhatunk a .NET keretrendszerünkhöz olyan osztálykönyvtárakat is, amelyek alaphelyzetben nem találhatók meg. Például letöltöttem az internetről egy olyan osztálykönyvtárt, amely elérhetővé teszi PDF fájlok tartalmát. Ennek osztályai közvetlenül nem láthatók a PowerShellből, de ha hozzáadom ezt a környezethez, akkor egyszerűen használhatók a benne található lehetőségek:
[3] PS C:\> Add-Type -Path C:\ee\PDF\dll\PdfSharp.dll
Persze nem árt tájékozódni az osztálykönyvtár lehetőségeit illetően, ehhez használhatjuk a .NET Reflector programot:
61 . ábra .NET Reflector az osztálykönyvtár felderítéséhez
Ezek után már megtippelhetjük, hogy egy PDF dokumentum beolvasásához például a PDFReader osztály Open metódusát használhatjuk:
[4] PS C:\> $doc = [PdfSharp.Pdf.IO.PdfReader]::Open("C:\ee\egy.pdf")
[5] PS C:\> $doc
Tag :
Options : PdfSharp.Pdf.PdfDocumentOptions
Settings : PdfSharp.Pdf.PdfDocumentSettings
Version : 14
PageCount : 1
FileSize : 95712
FullPath : C:\ee\egy.pdf
Guid : d609c42b-90c6-4223-b213-465f8983446d
IsImported : True
IsReadOnly : False
Info : {[/Author, þÿ S o ó s T i b o r], [/Creator, þÿ M i c r o s o f t ® W o r d 2 0 1 0], [/Creat
ionDate, D:20110405163010+02'00'], [/ModDate, D:20110420092850+02'00']...}
CustomValues : {}
Pages : {[/Type, /Page] [/Parent, 2 0 R] [/Resources, << /Font << /F1 5 0 R /F2 7 0 R >> /ProcSet [ /PDF /T
ext /ImageB /ImageC /ImageI ] >>] [/Annots, [ 12 0 R 13 0 R ]] [/MediaBox, [ 0 0 595.32 841.92 ]] [
/Contents, 4 0 R] [/StructParents, 0]}
PageLayout : SinglePage
PageMode : UseNone
ViewerPreferences : {}
Outlines : {}
AcroForm :
Language : hu-HU
SecuritySettings : PdfSharp.Pdf.Security.PdfSecuritySettings
Internals : PdfSharp.Pdf.Advanced.PdfInternals
SecurityHandler : {}
Owner :
IsIndirect : False
Reference :