Észszerűnek tűnik, hogy a PowerShell konzol tudjon adatokat fogadni a vágólapról, illetve a kimenetét is át lehessen oda irányítani. Természetesen a vágólap kezelésére létezik .NET osztály, a System.Windows.Forms.Clipboard a 2.0-s keretrendszerben a PowerShell 2.0 használóknak , de ezzel két probléma is adódik: az egyik, hogy az ezt definiáló .NET építőelem nincs a PowerShell alá betöltve, mivel a konzol ablaknak nincs szüksége erre. Szerencsére ez a probléma viszonylag egyszerűen orvosolható, be kell tölteni a megfelelő építőelemet. A másik probléma, hogy ez a vágólap-kezelő osztály csak un. Single Thread Arcitecture módban futó processzekkel kezelhető, márpedig a PowerShell a konzolban nem ilyen üzemmódban fut, így használata során hiba lépne fel. Ezt már egy fokkal nehezebb megoldani. Az egyik lehetőség az lenne, hogy magát a powershell.exe alkalmazást ebben az STA üzemmódban indítjuk, ami megoldható egy egyszerű –sta paraméter használatával, de ha egy általános megoldást szeretnénk, akkor minden olyan helyen át kellene alakítani a PowerShell futását, ahol a vágólapot használni szeretnénk, ami nem túl praktikus és egészen biztos egy „idegen” gépen ezt elfelejtjük.
Nézzünk egy olyan megoldást, ami nem igényli ezt az általános átállítását a PowerShell alkalmazásnak. Itt egy trükköt alkalmazok, PowerShellből hívom meg a PowerShellt, immár –sta üzemmódban. A vágólap közös, így ha ebből a második PowerShellből teszem ki az információt oda, az ugyanolyan jó. Szerencsére a paraméterátadás működik a hagyományos módon. Az ezt megvalósító függvény így néz ki:
function Out-ClipboardString
{
$input |
powershell -sta -command {
add-type
-a system.windows.forms
[System.Windows.Forms.Clipboard]::SetText(
($input | Out-String)
)
}
}
Az Out-ClipboardString függvény nem igényel hagyományos paramétert, az $input-ban felhalmozódott csőtartalmat adom át egy újabb PowerShell példánynak, amit STA üzemmódban indítok. Ebben a környezetben betöltöm a System.Windows.Forms .NET építőelemet, amelyben található a vágólap osztálya, és itt meghívom a SetText statikus metódust a sztringgé konvertált $input-ra.
Hasonló módon működik a vágólapról beolvasó függvényem. Itt egy paraméter adható meg opcionálisan, hogy mely karakter mentén tördelje szét a vágólapon tárolt szöveget. Ez alaphelyzetben a Windowsos soremelés karakterkombináció, de természetesen felülbírálható.
Function Read-ClipboardString
([string] $delimiter = "\r\n")
{
(powershell
-sta {add-type -a system.windows.forms
[System.Windows.Forms.Clipboard]::GetText()}) -split $delimiter
}
Nézzünk használatukra egy példát:
[10] PS C:\> Get-Service g* | Out-ClipboardString
[11] PS C:\> Read-ClipboardString
Status Name DisplayName
------ ---- -----------
Running gpsvc Group Policy Client
Stopped gupdate1ca2bfd6... Google Update Service (gupdate1ca2b...
Sok érdekesség nem látszik, gyakorlatilag a vágólapon keresztül sztringgé konvertált kimenethez jutottam. Az igazi felhasználása ennek az lehet, ha valamely más alkalmazással akarok ezen a módon adatot cserélni. Az így vágólapra helyezett információ természetesen beilleszthető például a Notepadbe:
139 . ábra Notepadbe illesztett vágólaptartalom
Látható, hogy ez nem volt egyszerű. Ha nem ragaszkodunk a .NET osztályokhoz, akkor használhatjuk még a parancssori Clip.exe segédprogramot is:
[19] PS C:\> Get-Service k* | clip
A végeredmény gyakorlatilag ugyanaz, mint a saját függvénnyel, valószínű kevesebb erőforrás felhasználásával és sokkal gyorsabban működik ez utóbbi megoldás.
Sokkal egyszerűbb dolgunk van a PowerShell 3.0 vagy frissebb használatával, hiszen az ezek alatt megbújó .NET 3.0 és újabb verziókban már a [system.windows.clipboard] típust használhatjuk. Nézzük ezzel az újabb Out-Clipboard függvényt:
Function Out-Clipboard {
Add-Type -AssemblyName PresentationCore
[windows.clipboard]::SetText(($input | Format-Table | Out-String))
}
A vágólap tartalmának eléréséhez egy másik trükköt is alkalmazhatunk. Függvény helyett csináljunk egy speciális „automatikus” változót, ami kiolvasásakor mindig a vágólap aktuális tartalmát adja meg:
$global:clipboard = New-Object -TypeName PSObject
Add-Member -InputObject $global:clipboard -MemberType ScriptMethod -Name ToString -Value {
Add-Type -AssemblyName PresentationCore
[windows.clipboard]::GetText()
} -Force
Ez a $clipboard változó egy olyan egyedi objektum, aminek nincs semmilyen tulajdonsága, viszont újra definiáltam a ToString() metódusát, ami egy olyan szkriptmetódus, ami megadja a vágólap tartalmát. Így minden olyan esetben, amikor kiíratjuk, jobb híján a ToString metódusa hívódik meg. Például a fenti bekezdés kimásolása után ez lesz a $clipboard tartalma:
PS C:\> $clipboard
Ez a $clipboard változó egy olyan egyedi objektum, aminek nincs semmilyen tula
jdonsága, viszont újradefiniáltam a ToString() metódusát, ami egy olyan szkrip
tmetódus, ami megadja a vágólap tartal-mát. Így minden olyan esetben, amikor k