Skryptowanie Windowsa: WSH

Kolejny wpis z serii „Windows tez da się łatwo oskryptować”, poprzedni notka dotyczyła prostych skryptów wiersza poleceń.

WSH, czyli Windows Script Host jest mechanizmem umożliwiającym skryptowanie systemu Windows w dużo większym stopniu i możliwościach niż proste skrypty powłoki. Host skryptów jest domyślnie instalowany wraz z systemem (od Windows 98), wraz z dwoma standardowymi interpreterami VBScript oraz JScript. A po doinstalowaniu odpowiednich bibliotek można również używać Perla, Pythona, czy jakiegokolwiek innego języka. Dzieje się tak, ponieważ cały mechanizm opiera się na wykorzystaniu obiektów COM/DCOM.

Za pomocą WSH można zrobić prawie wszystko w systemie, wiec idealnie nadaje się do wykorzystania w nieco bardziej złożonych skryptach niż sama powłoka poleceń.

Standardowo, aby się nie powtarzać odsyłam do MSDN, gdzie można znaleźć dużo niezbędnych informacji o hoście skryptów, w dziale jemu poświeconym – 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.

Jadrem 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 w systemie Windows: 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ą MessageBoxa, 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, zaimplementujmy wersję uniksowej aplikacji uptime, pokazującej nieprzerywany czas pracy systemu. Ja używam wersji w VBS:

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

Ogólny schemat byłby taki sam w JScripcie, jedynie różnice jakie byłyby widoczne to specyficzne właściwości i cechy języka…

Skrypt można wzbogacić o obsługę argumentów i sprawdzać uptime zdalnego systemu modyfikując zawartość stałej strComputer.

Jak widać VBS i JS bardzo dobrze nadaje się na pisanie prostych narzędzi systemowych związanych z obsługą samego systemu bądź nadzorowania czy pobierania informacji o jego stanie.

Do tego celu 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ń. Co na pewno będzie bardzo dobrym ułatwieniem przy wykorzystywaniu naszych nowych narzędzi spod wiersza poleceń.

Można tego w łatwy sposób dokonać 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 spsoć na modyfikowanie powiązań plików i menu kontekstowego w opcjach folderów/plików. Teraz musimy męczyć się z ręczną edycja rejestru, bo assoc i ftype tylko ustawiają akcję dla komendy open.

Nieco lepszym i szybkim rozwiązaniem jest skopiowanie gałęzi dla JS i VBS i zmodyfikowanie, tak aby zachować dodatkowe pozycje w menu kontekstowym do edycji, drukowania. Można 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 robiąc dla JS, a na koniec nie zapomnieć o dodaniu do zmiennej środowiskowej pathext nowych rozszerzeń .vbs_console;.js_console, aby bez problemu uruchamiać skrypty w konsoli bez podawania rozszerzenia.

Bardzo ciekawą funkcjonalnością jest możliwość tworzenia skryptów modułów w kilku różnych językach wraz z możliwością includowania plików. Wystarczy stworzyć plik XML o rozszerzeniu wsf z odpowiednią zawartością, aby nie ograniczać się do jednego pliku i języka w danym skrypcie.

Odwieczne pytanie, w czym pisać VBScript czy JScript?

Na to pytanie można szukać odpowiedzi nawet na MSDNie – Clinick’s Clinic on Scripting #1: VBScript or JScript?. Ja bym wybrał JScripta, prawie czysty JavaScript, składnia podobna do jeżyków C-style. VBScript za to polecany jest dla programistów VisualBasica.
Inna sprawa to taka, ze VBScript pomału umiera, ba już od jakiegoś czasu 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. Dlatego dla nowych adeptów poleca się właśnie tą wersję. 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źć w Script Center, natomiast dużo kodu w VBS w artykułach z cyklu Cześć Skrypciarze!, gdzie większość kodu została napisana w VBS. Niezliczone zasoby dostępne są w różnych miejscach sieci, wystarczy użyć dowolnej wyszukiwarki.

3 przemyślenia nt. „Skryptowanie Windowsa: WSH”

    1. Czy najlatwiej to chyba wzglednie od punktu widzenia. Bardzo malo uzywalem PS, wiec dla mnie latwiej innymi metodami, chocby Perlem ;)
      A wlasnie przez dyplomowke zapodzial sie gdzies kolejny wpis o skryptowaniu Windowsa, tym razem przy uzyciu Perla.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *