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.
Fanael:
07/07/2009 @ 14:50:22 | #1
A najłatwiej to windowsa oskryptować PowerShellem ;)
malcom:
08/07/2009 @ 15:39:59 | #2
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.
MalDevBlog » Skryptowanie Windowsa: Perl:
09/07/2009 @ 17:28:41 | #3
[...] ostatniej notce poświeconej WSH wspominałem, że można bez problemu “podłączyć” dowolny silnik i korzystać z [...]