Skryptowanie Windowsa: WSH
• tech • 962 słowa • 5 minut czytania
Ta notatka została oznaczona jako wymagająca dopracowania: mal-repo-code.
Zawartość wpisu może ulec zmianie, zatem zapraszam do ponownych odwiedzin w niedalekiej przyszłości :)
Kolejny wpis z serii “Windows też da się łatwo oskryptować”. Poprzednia notka dotyczyła prostych skryptów wiersza poleceń, a teraz przyszła pora na skryptowanie z wykorzystaniem WSH.
WSH, czyli Windows Script Host jest mechanizmem umożliwiającym skryptowanie systemu Windows w dużo większym stopniu i ze znacznie większymi możliwościami, niż proste skrypty powłoki. Host skryptów jest domyślnie instalowany wraz z systemem (od Windows 98) z dwoma standardowymi interpreterami VBScript oraz JScript. Po doinstalowaniu odpowiednich bibliotek można również używać Perla, Pythona, czy jakiegokolwiek innego języka. Zawdzięcza się to oparciu całego mechanizmu na wykorzystanie obiektów COM/DCOM. Za pomocą WSH można zrobić prawie wszystko w systemie, więc idealnie nadaje się do wykorzystania w bardziej złożonych skryptach niż sam wiersz poleceń.
Standardowo, aby się nie powtarzać odsyłam do MSDN-a, gdzie można znaleźć dużo niezbędnych informacji o hoście skryptów w dedykowanym mu dziale - Windows Script Host. Tytułem wstępu mogę powiedzieć jedynie tyle, że Windows Scripting Host bazuje na obiektowym modelu udostępniając szereg obiektów, z których można korzystać w celu uzyskania dostępu do różnych komponentów powłoki i systemu Windows.
Jądrem hosta jest obiekt o nazwie WScript, który zawsze istnieje i jest dostępny przynajmniej w jednym egzemplarzu. Za jego pomocą możemy uzyskać informacje o samym hoście oraz o wykonywanym skrypcie. Obiekt ten tworzy również wszelkie inne obiekty jakie chcemy wykorzystać w naszym skrypcie - metoda CreateObject. Bezpośrednio w modelu obiektowym WSH można utworzyć tylko dwa obiekty: WshShell oraz WshNetwork. Wszystko inne uzyskuje się poprzez wywołanie metod tych obiektów.
Istnieją dwie wersje hosta skryptów WSH: WScript i CScript. Wersje te różnią się tylko trybem działania, a dokładnie standardowym strumieniem wyjścia. WScript działa w trybie graficznym, dane z standardowego wyjścia prezentowane są w formie graficznej za pomocą MessageBox-a, natomiast CScript wyświetla komunikaty w wierszu polecenia - konsoli.
Obie wersje interpretują skrypty w postaci pliku tekstowego, wykonując zawarte w nim polecenia. Wybór parsera dokonywany jest na podstawie rozszerzenia pliku skryptu, ale za pomocą przełącznika /E
można ręcznie wybrać silnik w jakim zostanie uruchomiony skrypt.
Jako prosty przykład skryptu niech posłuży zaimplementowany przeze mnie odpowiednik uniksowej aplikacji uptime, pokazującej nieprzerywany czas pracy systemu. Wykorzystałem VBS-a:
Option Explicit
Const strComputer = "."
Dim objWMIService, objOS
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
For Each objOS In objWMIService.InstancesOf("Win32_OperatingSystem")
Dim objSWbemDateTime
Set objSWbemDateTime = CreateObject("WbemScripting.SWbemDateTime")
objSWbemDateTime.Value = objOS.LastBootUpTime
Dim seconds, hours, minutes, days
seconds = DateDiff("s", objSWbemDateTime.GetVarDate, Now)
days = Fix(seconds / 86400)
seconds = seconds - (days * 86400)
hours = Fix(seconds / 3600)
seconds = seconds - (hours * 3600)
minutes = Fix(seconds / 60)
seconds = seconds - (minutes * 60)
Dim strUptime
strUptime = hours & ":" & minutes & ":" & seconds
if (days = 1) then
strUptime = days & " day, " & strUptime
elseif (days > 0) then
strUptime = days & " days, " & strUptime
end if
WScript.Echo "Uptime: " & strUptime
next
Dla JScript-a ogólny schemat byłby taki sam, a jedyną widoczną różnicą byłyby specyficzne właściwości i cechy języka…
Ten prosty skrypt można wzbogacić o obsługę argumentów i za jego pomocą sprawdzać uptime zdalnego systemu, wystarczy modyfikować zawartość stałej strComputer
definiującej nazwę hosta komputera.
Jak widać VBS i JS bardzo dobrze nadają się do tworzenia prostych narzędzi systemowych związanych z obsługą samego systemu, bądź jego nadzorowania, czy też pobierania informacji o jego stanie.
Do łatwego używania, takich skryptów i narzędzi spod wiersza poleceń, warto zarejestrować w systemie dodatkowy typ plików np. vbs_console i js_console, który domyślnie będzie uruchamiał skrypty o takim rozszerzeniu w trybie wiersza poleceń. Można to wykonać w łatwy sposób wprost z konsoli za pomocą polecenia assoc
i ftype
, jak przedstawiono na stronie How to directly call console-mode VBScript programs from the command-line.
Taka mała dygresja. Czemu w Viście usunięto łatwy i prosty sposób na modyfikowanie powiązań plików i menu kontekstowego w opcjach folderów/plików. Teraz musimy męczyć się z ręczną edycją rejestru, bo wspomniane polecenia assoc
i ftype
tylko ustawiają akcję dla komendy open.
Lepszym i szybszym sposobem może być skopiowanie gałęzi dla JS i VBS wraz z małymi modyfikacjami w celu zachowania dodatkowych pozycji w menu kontekstowym do edycji, drukowania. Wystarczy zaimportować poniższy fragment rejestru, zmieniając ścieżkę do swojego ulubionego edytora:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.vbs_console]
@="VBSConsoleFile"
[HKEY_CLASSES_ROOT\VBSConsoleFile]
@="VBScript Console File"
[HKEY_CLASSES_ROOT\VBSConsoleFile\DefaultIcon]
@="C:\\Windows\\System32\\WScript.exe,3"
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell]
@="Open"
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell\Edit]
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell\Edit\Command]
@="C:\\Program Files (x86)\\PSPad editor\\PSPad.exe \"%1\""
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell\Open]
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell\Open\Command]
@="C:\\Windows\\System32\\CScript.exe /E:vbscript /Nologo \"%1\" %*"
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell\Open2]
@="Open &with Explorer"
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell\Open2\Command]
@="C:\\Windows\\System32\\WScript.exe /E:vbscript \"%1\" %*"
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell\Print]
[HKEY_CLASSES_ROOT\VBSConsoleFile\Shell\Print\Command]
@="C:\\Windows\\System32\\Notepad.exe /p %1"
Analogicznie przeprowadzając operację to dla JS-a. A dodanie do zmiennej środowiskowej pathext
nowych rozszerzeń .vbs_console;.js_console pozwoli bez problemu uruchamiać skrypty w konsoli bez podawania ich rozszerzenia.
Ciekawostką jest możliwość tworzenia skryptów-modułów w kilku różnych językach. Służą do tego pliki XML o rozszerzeniu wsf. Dzięki temu nie trzeba się ograniczać do jednego pliku i języka w danym skrypcie.
Na koniec pojawia się pytanie - w czym pisać skrypty pod WHS - VBScript czy JScript?
Na to pytanie można szukać odpowiedzi nawet na MSDNie - Clinick’s Clinic on Scripting #1: VBScript or JScript?. Ja osobiscie bym wybrał JScript-a, bo to prawie czysty JavaScript i składnia podobna do języków C-podobnych. VBScript jest za to polecany dla programistów Visual Basica. Inną sprawą jest fakt, że VBScript pomału umiera śmiercią naturalną. Mimo, iż to właśnie w nim można znaleźć najwięcej napisanych skryptów, to jednak Microsoft wybrał JScripta - wypuszczając jego wersje na platformę .NET - JScript.NET. O powolnym umieraniu VBSa ciekawy wpis na blogu Erica Lipperta - Rumours of VBScript’s Death Have Been Greatly Exaggerated.
Warto pobrać sobie dokumentacje dla Windows Script 5.6, która w jednym pliku chm zawiera referencje dla VBS i JS oraz WSH, czyli o tym wszystkim o czym powinieneś wiedzieć bawiąc się skryptami w hoście skryptów Windowsa.
Garść informacji o skryptowaniu Windowsa można znaleźć też na Script Center, Natomiast dużo kodu w VBS dołączano w artykułach z cyklu Cześć Skrypciarze!. No i niezliczone zasoby dostępne są w różnych miejscach sieci…
Komentarze (2)
A najłatwiej to windowsa oskryptować PowerShellem ;)
Czy najłatwiej to chyba względnie od punktu widzenia. Bardzo mało używałem PS-a, więc dla mnie łatwiej jest innymi metodami, choćby Perlem ;)
A właśnie przez dyplomówkę zapodział się gdzieś kolejny wpis o skryptowaniu Windowsa, tym razem przy użyciu Perla.