Triki z PowerShellem #1 – GUIWindows PowerShell jest oczywiście powłoką tekstową z wierszem poleceń. Wszystkie więc czynności, jakie możemy w nim wykonać, wiążą się z wpisywaniem tychże poleceń i odczytywaniem wyników, podawanych także w postaci tekstowej. Prosto, minimalistycznie i naturalnie.
I właśnie dlatego jednym z pierwszym eksperymentów, jakie przy użyciu tego narzędzia wykonałem, była... próba wyświetlenia okienka z GUI :) Najpierw miało to być skromne okienko komunikatu (message box), jednak szybko okazało, że nie będzie to wcale łatwe. Domyślnie w PowerShellu nie jest bowiem załadowane assembly System.Windows.Forms, które to jest niezbędnie potrzebne do zabawy z okienkami. Nie oznacza to na szczęście, że oprócz jego załadowania należy też korzystać z niewygodnego interfejsu refleksji, aby cokolwiek przy jego użyciu zrobić (np. stworzyć obiekt klasy i wywołać jego metodę). Wystarczy po prostu jedno wywołanie w stylu:
i od tej pory można już zupełnie normalnie korzystać z Windows.Forms... No, prawie. Możemy w każdym razie uraczyć się okienkiem komunikatu:
A gdy już na nie popatrzymy, to pewnie zechcemy też czegoś więcej - na przykład "prawdziwego" okna, czyli zwykłej formy. To także jest do zrobienia:
Bez większego problemu można by zresztą dodać do formy kontrolki potomne, jak przyciski czy pola tekstowe... Jest jednak jeden poważny problem: właściwie nie ma sposobu na podpięcie pod nasze kontrolki procedur zdarzeniowych - nawet mimo tego, że przy użyciu wyjątkowo perfidnej sztuczki da się w PowerShellu tworzyć delegaty. Stworzone okienka pozostaną więc na wpółmartwe i specjalną funkcjonalnością nas nie zaskoczą.
Vista i Eksplorator gierOprócz wsparcia dla wielkiej i wspaniałej wersji 10 biblioteki DirectX, system Windows Vista ma przynajmniej jeszcze jeden feature związany z programowaniem gier (i przy okazji z graniem w nie). Nie jest on aczkolwiek aż tak szeroko znany, chociaż wszystkie niezbędne narzędzia potrzebne do korzystania z niego są zawarte - nomen omen - w DirectX SDK.
To Eksplorator gier - małe, dosyć niepozorne, ale w gruncie rzeczy całkiem potężne narzędzie - w tym sensie, że potrafi ono czasami... zablokować dostęp do niektórych plików na dysku :) To aczkolwiek robota kontroli rodzicielskiej, czyli funkcji bardzo ściśle z wspomnianym Eksploratorem związanej. Ale po kolei.
Eksplorator gier (dostępny przez Start > Gry) to program, za pomocą którego możemy przeglądać gry zainstalowane na naszym komputerze. Prezentuje on nam ich nazwy, loga, gatunki, wymagania sprzętowe (w postaci Indeksu wydajności Windows), klasyfikację treści (wymagany wiek, zawartość przemocy, wulgaryzmów, itp.) i oczywiście pozwala także rzeczone gry uruchamiać - o ile nie zabrania tego ewentualna kontrola rodzicielska. Niby proste, chociaż na pierwszy rzut oka można by przypuszczać, że aplikacja ta dysponuje jakąś sztuczną inteligencją lub zdolnościami paranormalnymi. No bo skąd właściwie bierze ona te wszystkie informacje?...
Prawda jest naturalnie taka, że wszystkie te dane muszą być podane przez twórców gier. W tym celu należy stworzyć tzw. Game Definition File (GDF), który jest plikiem XML opisującym różne parametry gry. Do niego możemy też dołączyć kilka grafik, a następnie całość należy zlinkować jako zasoby (resources) do jakiegoś pliku wykonywalnego - .exe lub .dll. Część tych czynności jest wspomagana przez Game Definition File Editor - niewielkie narzędzie dostarczane wraz z DirectX SDK począwszy od zeszłego roku. Potrafi ono mianowicie wyprodukować skrypt zasobów (plik .rc), który możemy dołączyć np. do projektu w Visual C++, skompilować do .res i z linkować z naszą grą.
Lecz niestety nie jest to koniec zabawy :) Cały ten system, dzięki któremu Eksplorator posiada informacje o zainstalowanych grach, działa częściowo w oparciu o COM, a sama gra wymaga rejestracji w systemie w dość specjalny sposób, zanim będzie ona widoczna w programie. Ten sposób spokojnie można nazwać "ręcznym", bo obejmuje on:
IGameExplorer.VerifyAccess z podaniem pliku GDF.AddGame z kilkoma parametrami, m.in. wspomnianym plikiem i ścieżką do katalogu instalacyjnego gry.Urocze, prawda? ;-) Żeby było śmieszniej, wszystkie te czynności powinny być wykonane w trakcie instalacji gry (a dokładniej: na sam jej koniec), co wymaga intensywnej grzebaniny w używanym programie instalacyjnym (w celu wywołania funkcji z pomocniczej biblioteki DLL) lub po prostu napisania małego programiku, który zostanie odpalony na końcu setupu i wszystkim się zajmie. O ile mi wiadomo, ani InstallShield, ani Windows Installer, ani freeware'owy Inno Setup nie wspierają natywnie procesu rejestracji gier w podobny sposób jak chociażby instalacji czcionek w systemie.
"A więc po co to wszystko?", można zapytać. Ano chociażby po to, żeby nasza cudna produkcja jakoś się wyróżniała :] Obecnie gry retailowe w większości rejestrują się Eksploratorze, lecz z pewnością czyni tak mniejszość gier typu casual czy share/freeware. Możemy więc choć trochę zabłysnąć w oczach przyszłego użytkownika (chociaż zasadniczo zalecam świecenie innymi zaletami).
Na koniec - jeśli zdecydujemy pobawić się całym tym mechanizmem - warto pamiętać o tym, że Eksplorator gier to rzecz istniejąca jedynie na Viście, więc tylko na tym systemie powinniśmy przeprowadzać proces rejestracji.
Konsolka dla okienZasadniczo to systemy uniksowe znane są z intensywnego wykorzystania trybu tekstowego, czyli wiersza poleceń konsoli. W przypadku systemu Windows wydaje się, że jest to bardziej pozostałość po starym (nie)dobrym DOS-ie, która została prawie całkowicie zastąpiona przez interfejs graficzny. Problem jednak w tym, że nie wszystko da się zawsze wygodnie wyklikać - a co więcej, takie czynności niezbyt nadają się do zautomatyzowania (na przykład po to, aby wielokrotnie przeprowadzać zmiany w konfiguracji na wielu maszynach). Mając elastyczny tryb tekstowy, zwykle bowiem wystarczy napisać odpowiedni skrypt; w przypadku trybu graficznego nie ma takiej możliwości.
Ten mankament był w Windows obecny od dawna i różne były sposoby na jego obejście - począwszy od plików wsadowych (.bat) przez eksporty/importy Rejestru (.reg), pliki .inf czy skrypty WSH (Windows Scripting Host). Te ostatnie są na przykład znane z powodu... kilku wirusów, które zdołały się szeroko rozprzestrzenić, wykorzystując tę technologię (np. słynny I.Love.You).
Wszystkie podobne pomysły rozwiązywały jednak cały problem dość średnio. Lecz od jakiegoś czasu istnieje Windows PowerShell, który wydaje się znacznie ciekawszym rozwiązaniem. Jest to tekstowa powłoka poleceń - wraz ze skryptowym językiem programowania - która nie tylko jest o wiele bardziej przydatna niż wcześniejsze wynalazki Microsoftu, ale też wypada wcale nieźle w porównaniu z innymi shellami, jak choćby bash. Ma ona bowiem kilka interesujących cech szczególnych:
W tym momencie zapewne przydałby się wymowny przykład, który może wyglądać choćby następująco:
To polecenie najpierw listuje wszystkie procesy w systemie (ps), następnie wybiera spośród nich te, które nie odpowiadają, aby w końcu posłać je do Krainy Wiecznych Zwisów :) Operujemy tutaj na obiektach reprezentujących procesy, a jedną z ich właściwości jest, jak widać, Responding, którą można użyć do filtrowania.
W pełnej wersji komenda wyglądałaby tak naprawdę następująco:
co być może wygląda wymowniej, lecz jest z pewnością bardziej rozwlekłe. Na szczęście PowerShell definiuje fabrycznie kilkanaście aliasów, które mapują się na polecenia odpowiadające z grubsza tym znanym z innych shelli - jak dir, ls, cd, rm, ps, man czy type. To pozwala w miarę szybko poznać podstawowe komendy i przyspiesza ich wpisywanie.
Na koniec trzeba stwierdzić, że przydatność PowerShella zależy prawdopodobnie przede wszystkim od tego, czy potrafimy wykorzystać całe to ogromne bogactwo klas .NET, COM i WMI, które powłoka ta udostępnia. Jeśli tak, to możemy znaleźć dla niej szerokie pole zastosowań. Polecam w każdym razie przyjrzenie się temu wynalazkowi (dostępnemu na każdą sensowną wersję Windows, tj. od XP SP2 wzwyż). Sam lubię używać go do zabijania procesów znacznie bardziej niż standardowego Menedżera zadań ;-)
Wielkanocne jajaWprawdzie Google ostatecznie rozstrzyga rywalizację między Gwiazdką a Wielkanocą na korzyść tej pierwszej, ale to zwyczaj z okolic święta wiosennego użyczył nazwy dla pewnej zabawnej praktyki programistycznej. Chodzi o easter eggs, czyli ukryte napisy, ekrany, a czasem całe pod-aplikacje, obecne w programie acz niedostępne niewtajemniczonym użytkownikom. Mimo tego, wiele spośród tych 'jaj' stało się wyjątkowo znanych.
Dotyczy to naturalnie tych aplikacji, które są szeroko znane - czyli na przykład tych wyprodukowanych przez znaną i (nie)lubianą firmę z Redmond. Różne wersje pakietu Office zawierają przykładowo przynajmniej kilka różnych gier, począwszy od prostego flippera (Word 97) przez symulator lotu aż po... grę FPP (we wczesnej wersji Excela). W Windows poniżej wersji XP można było też wykorzystać ciekawostkę ukrytą w jednym z wygaszaczy ekranu, który mógł wyświetlać kolejno nazwy znanych wulkanów na świecie.
Spora ilość easter eggs jest zawarta w okienkach About programów - co jest całkiem zrozumiałe, zważywszy że prawie nikt tam nie zagląda :) Do bardziej znanych należy chyba odgłos wydawany po kliknięciu w nos na fotografii twórcy programu mIRC.
Jaja możemy jednak znaleźć nie tylko w programach użytkowych, ale także w grach. Kto nie zna słynnego "krowiego poziomu" (cow level) z Diablo II? Blizzard ma zresztą więcej takich kwiatków w zanadrzu - jak choćby zabawne dźwięki wydawane przez jednostki w obu znanych RTS-ach (WarCraft i StarCraft). W World of Warcraft ilość różnych smaczków liczy się co najmniej w tysiącach.
Niestety, przed easter eggs przyszłość rysuje się ponuro. Możliwość umieszczenia w kodzie programu nieudokumentowanego kodu jest bowiem potencjalnym zagrożeniem i może prowadzić do powstania tzw. bomb logicznych. To oczywiście zmartwienie koncernów, które mogą nie ufać swoim programistom. Amatorskich produkcji siłą rzeczy to nie dotyczy.
Tak więc umieszczajmy w swoich grach i aplikacjach jak najwięcej jajcarskich pomysłów, póki jeszcze możemy :) Wesołych świąt!
Łapacz pakietówOprogramowanie open source nie grzeszy zazwyczaj jakością, lecz od każdej reguły istnieją przecież wyjątki. Ostatnio znalazłem właśnie taki wyjątek; należy on do tej kategorii programów, które wymagają pewnego przygotowania, jeśli chcemy z nich korzystać efektywnie. Lecz mimo tego, iż jest to dość specjalistyczne narzędzie, nie sposób przy jego pomocy zrobić krzywdy swojemu systemowi. Warto się więc mu przyjrzeć, bo wśród tego rodzaju programów jest ono prawdopodobnie jednym z najlepszych.
Mam na tu na myśli analizator pakietów sieciowych Wireshark. Przy jego pomocy możemy bez większych problemów podejrzeć, cóż takiego jest przesyłane wzdłuż biegnących od naszego komputera kabli (względnie fal radiowych). Takie programy są popularnie nazywane snifferami i mogą służyć do bardzo wielu pożytecznych celów oraz kilku innych, mniej chwalebnych ;-)
Wśród wyróżniających cech Wiresharka trzeba na pewno wymienić interfejs, który jest przejrzysty, a przy tym funkcjonalny - co nie zdarza się często nawet wśród nie-GPL-owych programów. Bez większych problemów możemy złapane pakiety przeglądać i filtrować według wielu różnych kryteriów. Mogą one obejmować także cechy dot. specyficznych protokołów sieciowych (możemy np. wyświetlić pakiety HTTP z żądaniami typu GET). A tych wspieranych przez program jest zresztą całkiem sporo. Pakiety należące do znanych protokołów są oczywiście automatycznie rozkodowywane i pokazywane w przyjaznej postaci z podziałem na warstwy OSI, pola w nagłówkach oraz zasadniczą treść.
To oczywiście nie wszystko; do innych bardzo użytecznych funkcji należy chociażby możliwość wyodrębnienia całego strumienia TCP (czyli np. "rozmowy" jakiejś aplikacji ze zdalnym serwerem). Podobnie przydatnych narzędzi jest zresztą więcej i ciężko byłoby je wszystkie tu wymienić.
Dodatkowo program ten jest wybitnie wszędobylski i posiada równoważne wersje dla prawie każdego sensownego systemu operacyjnego, z Windows i przeróżnymi Linuksami włącznie. Biorąc pod uwagę to, że działa sprawnie, szybko i intuicyjnie, trzeba przyznać, że to nieoceniony instrument dla programisty piszącego aplikacje sieciowe.
Prawie jak mapa kodu
Do pisania programów wystarczy dowolny edytor tekstu i linia poleceń, ale dzisiaj trudno przecenić wygodę, jaką dają zintegrowane środowiska programistyczne (IDE). I chociaż każda porządna aplikacja tego typu - niezależnie od języka, dla którego jest przeznaczona - posiada pewną określoną i oczywistą funkcjonalność (jak choćby rozbudowane zarządzanie projektami), to w wielu można znaleźć drobne i interesujące dodatki.
Taki NetBeans (IDE do Javy) posiada na przykład pasek boczny, widoczny po prawej stronie paska przewijania w polu z kodem. Reprezentuje on cały otwarty plik, zaś naniesione na niego kreski odpowiadają linijkom, w których "dzieje się" coś potencjalnie interesującego. Mogą to być wiersze zawierające błędy kompilacji albo wystąpienia identyfikatora (nazwy), w którym aktualnie znajduje się kursor. Najważniejsza cechą tych wskaźników jest to, że można w nie klikać i w ten sposób przenosić się do odpowiednich miejsc w kodzie.
Według mnie to całkiem zmyślne rozwiązanie, przydatne zwłaszcza przy poprawianiu błędów, gdyż oszczędza przechodzenia do okienka z outputem kompilatora, a potem z powrotem do kodu. Jego użyteczność może się aczkolwiek ujawnić najlepiej tylko w przypadku, gdy IDE przeprowadza kompilację w tle i na bieżąco podkreśla i zaznacza napotkane błędy.
Standard i Visual C++ 2005Zainspirowany pewnym wątkiem na forum Warsztatu, traktującym o rzekomych poważnych niezgodnościach między standardem C++ a kompilatorem zawartym w MS Visual C++ 2005, postanowiłem nieco dogłębniej zbadać tę sprawę. Jak dotąd z owych niezgodności kojarzyłem tylko brak wsparcia dla szablonów eksportowanych - czyli "magicznego" słówka export, pozwalającego na rozdzielanie kodu szablonowego na pliki nagłówkowe i pliki .cpp tak samo, jak zwykłego. Nie jest to zresztą wielkie wykroczenie, jako że kompilatory wspierające szablony eksportowane można pewnie policzyć na palcach jednej ręki, a sam mechanizm też nie należy do szeroko znanych.
Co z innymi niezgodnościami? Odwołanie do dokumentacji Visual C++ przynosi ich jeszcze kilka. Z ciekawszych - oprócz braku obsługi słowa export, o którym już wspomniałem - mogę wymienić:
\n, \t, itd.).throw (typ_wyjątku)). Innymi słowy, w Visual C++ nie sprawdza się, czy funkcja wyrzuciła wyjątek takiego samego typu, który wcześniej został w niej zadeklarowany.I to mniej więcej tyle. Być może kogoś zmartwi brak możliwości napisania algorytmu ze 100 zagnieżdżonymi pętlami lub szablonu z tyloma parametrami, ale osobiście mam co do tego pewne wątpliwości :)