Új típusok létrehozása (Add-Type)

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         :



Word To HTML Converter