Centrum skryptów - Systemy operacyjne

Jak pobrać wszystkie wartości z klucza rejestru?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak pobrać wszystkie wartości z klucza rejestru?

Cześć, Skrypciarze! Czy macie może w zanadrzu skrypt, który umożliwi mi wyliczenie wszystkich wartości znajdujących się w kluczu rejestru?

-- DG

Cześć, DG. Wiecie co, w zeszły weekend wyszedłem z domu, żeby kupić pączki i zajęło mi to o wiele więcej czasu niż powinno. Dlaczego kupno pączków zajęło mi tyle czasu? Ponieważ kobieta na początku kolejki z uporem maniaczki maglowała sprzedawcę w sprawie wartości odżywczej każdego z osobna pączka znajdującego się w witrynie wystawowej. W którymś momencie zamyśliła się na chwilę, „Więc, jaka opcja jest pana zdaniem najzdrowsza?”

Rety, kobieto, to jest budka z pączkami – tak sobie pomyślałem – najzdrowszą opcją będzie wziąć nogi za pas i zmiatać. Najzdrowsza opcja? Wielkie nieba, samo przyjście tutaj kosztowało ją dwa lata życia.

Ciiiii.

Tak czy inaczej, sprzedawca pączków, który okazał się o wiele cierpliwszy i pełen zrozumienia niż ja, polecił pączka z jagodami. Tak z czystej ciekawości postanowiłem sprawdzić wartość odżywczą pączka z jagodami w porównaniu z tradycyjnym pączkiem z polewą czekoladową. (Czy zrobiłem to w czasie pracy? Mhm, cóż. Nie pamiętam już skąd mam te informacje…).

Oto, co znalazłem:

- Pączek z jagodami Pączek z polewą
Kalorie 290 210
Tłuszcz 16 g 10 g
Kalorie pochodzące z tłuszczu 140 90

 

Innymi słowy pączek z jagodami jest w zasadzie mniej zdrowy niż pączek z polewą. Czy to oznacza, że sprzedawca naprawdę się pomylił, czy chciał, żeby ta kobieta zjadła pączka z jagodami, mając nadzieję, że padnie martwa na miejscu i nigdy już nie wróci, żeby męczyć go głupimi pytaniami o to, który pączek jest najzdrowszy? Nie mam pojęcia: ja tylko chciałem kupić kilka pączków (nieważne z czym) i wrócić do domu.

Prawda jest taka, że sklepik z pączkami nie jest miejscem, w którym należy szukać zdrowej żywności. Takich rzeczy należy szukać w Centrum skryptów, gdzie mamy szeroki wachlarz różnych zdrowych opcji. Weźmy na przykład skrypt wyliczający wszystkie wartości (i wartości tych wartości) znajdujące się w kluczu rejestrów: Na zdrowie:

Const HKEY_CURRENT_USER = &H80000001



Const REG_SZ = 1

Const REG_EXPAND_SZ = 2

Const REG_BINARY = 3

Const REG_DWORD = 4

Const REG_MULTI_SZ = 7

 

strComputer = "."

 

Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

 

strKeyPath = "Software\Microsoft\Internet Explorer\Main"

objRegistry.EnumValues HKEY_CURRENT_USER, strKeyPath, arrValueNames, arrValueTypes

 

For i = 0 to UBound(arrValueNames)

    strText = arrValueNames(i)   

    strValueName = arrValueNames(i)



    Select Case arrValueTypes(i)

        Case REG_SZ

            objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,strValue 

            strText = strText & ": "  & strValue

        Case REG_DWORD

            objRegistry.GetDWORDValue HKEY_CURRENT_USER,strKeyPath, strValueName, intValue    

            strText = strText & ": "  & intValue

        Case REG_MULTI_SZ

            objRegistry.GetMultiStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,arrValues  

            strText = strText & ": "

            For Each strValue in arrValues

                strText = strText & "   " & strValue 

            Next  

        Case REG_EXPAND_SZ

            objRegistry.GetExpandedStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,strValue    

            strText = strText & ": "  & strValue

       Case REG_BINARY

            objRegistry.GetBinaryValue HKEY_CURRENT_USER,strKeyPath, strValueName,arrValues    

            strText = strText & ": "

            For Each strValue in arrValues

                strText = strText & " " & strValue 

            Next  

        End Select 



    Wscript.Echo strText

Next

Jak więc ten skrypt wpływa na nasze zdrowie? Czy ja wyglądam na lekarza? Nie umiem wam tego wyjaśnić, ale na pewno jakoś wpływa.

Z pewnością nie jest w stanie pogorszyć niczyjego zdrowia.

O ile mi wiadomo oczywiście.

Wiecie co? Odstawmy na bok tę całą gadaninę o wartościach odżywczych i zobaczmy, jak ten skrypt działa. Jak widać, zaczynamy od zdefiniowania całej masy stałych. Stała HKEY_CURRENT_USER poinformuje skrypt, z którą gałęzią rejestru będziemy pracować. Pozostałe stałe posłużą nam do określenia typu danych poszczególnych wartości rejestru, które znajdziemy. Przykładowo w usłudze WMI wartość rejestru o typie danych 1 jest wartością o typie danych REG_SZ. Dlatego też przypisujemy wartość 1 do stałej REG_SZ:

Const REG_SZ = 1

Wydaje się to zasadne i zdrowe, nieprawdaż?

Po zdefiniowaniu wszystkich stałych łączymy się z usługą WMI na komputerze lokalnym. Tak, możemy uruchomić ten skrypt na komputerze zdalnym. Wystarczy tylko przypisać nazwę tego komputera zdalnego do zmiennej o nazwie strComputer:

strComputer = "."

Skoro już o tym mówimy, powinniśmy przyjrzeć się bliżej ciągowi połączenia usługi WMI:

Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

Jeżeli chodzi o ten ciąg, należy pamiętać o dwóch rzeczach. Po pierwsze, należy zauważyć, że łączymy się z przestrzenią nazw root\default. To trochę niezwykłe. Zazwyczaj podczas tworzenia skryptów WMI łączymy się z przestrzenią nazw root\cimv2. Zauważcie także, że łączymy się bezpośrednio z klasą StdRegProv. To dlatego, że wszystkie metody używane w rejestrze to metody „statyczne”, co oznacza, że działają w stosunku do klasy jako całości, a nie pojedynczych wystąpień klasy.

Uwaga. Nie martwcie się tym zbytnio. Trochę się popisuję. A sporo już o popisach mowa, to czy wiedzieliście, że w 1998 roku ciastkarnia Winchell’s Doughnuts zrobiła pączka, który ważył ponad 2 kg i miał prawie 30 cm średnicy? To smutne, ale ten pączek nigdy nie znalazł się w menu.

Po połączeniu się z usługą WMI używamy poniższego wiersza kodu do przypisania żądanej ścieżki rejestru (w gałęzi HKEY_CURRENT_USER) do zmiennej o nazwie strKeyPath:

strKeyPath = "Software\Microsoft\Internet Explorer\Main"

Po wykonaniu tej czynności możemy zastosować metodę EnumValues w celu pobrania kolekcji wszystkich wartości rejestru znajdujących się w tym kluczu rejestru:

objRegistry.EnumValues HKEY_CURRENT_USER, strKeyPath, arrValueNames, arrValueTypes

Teraz przechodzimy to bardziej pokopanej części skryptu. Na początek zauważmy, że metoda EnumValues przekaże nam nazwy i typy danych dla wszystkich wartości znajdujących się w danym kluczu rejestru. (Jednak nie wartości znajdujących się w podkluczach tego klucza rejestru. Do tego potrzebna nam jest funkcja rekurencyjna (j. ang.). Przykładowo nasz skrypt mówi nam, że główny klucz rejestru zawiera wartość o nazwie Anchor Underline oraz że ta wartość Anchor Underline to typ danych REG_SZ. Fajnie, ale czy wartość właściwości Anchor Underline ustawiona jest na yes, czy na no? Tego metoda EnumValues nam nie powie. Sami będziemy musieli się tego dowiedzieć.

Ale nie rozpaczajcie. Dopóki znamy nazwy i typy danych wartości, samo znalezienie faktycznych wartości nie jest aż takie trudne. (Może trochę skomplikowane, ale nie strasznie trudne). Być może zauważyliście, że podczas wywoływania metody EnumValues przekazaliśmy jej cztery parametry:

  • HKEY_CURRENT_USER, stała informująca skrypt, na której gałęzi rejestru ma działać.
  • strKeyPath, zmienna informująca skrypt, na którym kluczu rejestru ma działać.
  • arrValuesNames, parametr „out”, który metoda EnumValues zapełni nazwami każdej wartości znalezionej w kluczu rejestru. Parametr out to po prostu parametr przechowujący dane przekazane przez metodę. Przekazujemy metodzie EnumValues nazwę zmiennej, a metoda EnumValues przekazuje nam nazwy wszystkich wartości rejestru i przypisuje te informacje do naszego parametru out.
  • arrValueTypes, kolejny parametr out. Ten ma za zadanie przechowywać typ danych każdej wartości znajdującej się w kluczu rejestru.

Co więc robimy z wszystkimi informacjami przekazanymi przez metodę EnumValues ? Cóż, na początek uruchamiamy pętlę For Next, która przejdzie przez tablicę zawierającą nazwy wartości (arrValueNames):

For i = 0 to UBound(arrValueNames)

Wewnątrz tej pętli przypisujemy nazwę pierwszej wartości rejestru do dwóch zmiennych:

strText = arrValueNames(i)   

strValueName = arrValueNames(i)

Zmienną strText wykorzystamy do przechowywania zarówno nazwy każdej wartości rejestru oraz – jak tylko ją pobierzemy – wartości każdej wartości rejestru. W międzyczasie zastosujemy zmienną strValueName do reprezentowania tej właśnie wartości podczas próby pobrania, no cóż, wartości tej wartości.

Uwaga. Czy możliwe jest użycie słowa wartość więcej razy w jednym zdaniu? Miejmy nadzieję, że nie.

Za każdym razem, kiedy Skrypciarze dokonują odczytu z rejestru, korzystają z WMI zamiast Hosta skryptów systemu Windows. Dlaczego? Bynajmniej nie dlatego, że łatwiej jest używać WMI. Tak naprawdę używanie WMI jest wiele trudniejsze, niż używanie Hosta skryptów systemu Windows. To dlatego, że WMI wymaga zastosowania innej metody dla każdego typu danych rejestru. Jeśli mamy wartość o typie danych REG_SZ, musimy użyć metody GetStringValue. Jeśli mamy wartość o typie danych REG_DWORD, musimy użyć metody GetDWORDValue. Host skryptów systemu Windows umożliwia nam odczyt każdych danych za pomocą jednej metody: RegRead.

Dlaczego wiec zazwyczaj używamy WMI zamiast Hosta skryptów systemu Windows? Z jednego tylko powodu: WMI umożliwia nam odczyt rejestru na komputerze zdalnym. Host skryptów tego nie potrafi.

W każdym razie fakt, że WMI wymaga różnych metod dla różnych typów danych wyjaśnia obecność poniższego wiersza kodu:

Select Case arrValueTypes(i)

Sprawdzamy tutaj typ danych dla pierwszej wartości rejestru. Załóżmy, że ta wartość ma typ danych REG_SZ (pamiętajmy, że zdefiniowaliśmy stałą o nazwie REG_SZ na samym początku tego skryptu). W takim przypadku użyjemy metody GetStringValue w celu odczytania wartości z rejestru, a następnie dodamy tę wartość do zmiennej strText:

Case REG_SZ

    objRegistry.GetStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,strValue

       strText = strText & ": "  & strValue

Chyba nie muszę dodawać, że jeżeli nasza wartość ma inny typ danych, użyjemy innej metody. Zauważyliście zapewne, że zarówno GetMultiStringValue, jak i GetBinaryValue przekazują dane w postaci tablicy. To oznacza, że musimy uruchomić pętlę For Each w celu dostania się do wszystkich wartości w tej tablicy:

Case REG_MULTI_SZ

    objRegistry.GetMultiStringValue HKEY_CURRENT_USER,strKeyPath, strValueName,arrValues  

    strText = strText & ": "

        For Each strValue in arrValues

            strText = strText & "   " & strValue 

        Next

Po wywołaniu echa wartości zmiennej strText wracamy na początek pętli, gdzie powtarzamy proces dla następnej nazwy w tablicy arrValueNames. Po wykonaniu wszystkich czynności powinniśmy otrzymać mniej więcej taki wynik:

NoUpdateCheck: 1

NoJITSetup: 1

Disable Script Debugger: no

Show_ChannelBand: No

Anchor Underline: yes

Cache_Update_Frequency: Once_Per_Session

Display Inline Images: yes

Itd. Itp.

To powinno wystarczyć, DG. Pójdę poszukam sobie czegoś zdrowego do jedzenia.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne