Rejestry systemu Windows
Pełna, aktualna wersja tego artykułu znajduje się pod w artykule Rejestry i pliki INI.
W pierwszej kolejności należy odpowiedzieć czym jest rejestr Windows. Kliknij na menu Start, a następnie na pozycje Uruchom. W polu tekstowym wpisz "regedit". Otworzy się edytor rejestru. Zobaczysz tam ogromną ilość pozycji. W tym artykule te foldery będę nazywał kluczami, a pozycje w prawej części okna będę nazywał wartościami rejestru. No, ale nie odpowiedziałem na najważniejsze pytanie: czym jest rejestr? Co prawda Microsoft zaprzecza ale jest to ogromne źródło informacji o naszym systemie, zainstalowanych programach, konfiguracji itp. Manipulowanie rejestrem bez znajomości rzeczy grozi poważnymi konsekwencjami - złym działaniem programu, błędami albo nawet niemożnością uruchomienia systemu. Także programy, które instalujesz w swoim systemie wykorzystują rejestr Windows. Zapisują w nim swoją konfiguracje. Pomyśl, włączasz program, ustawiasz konfiguracje, zamykasz program i uruchamiasz go ponownie, a konfiguracja jest ustawiona tak samo! Gdzie program te ustawienia przechowuje? Albo w rejestrze, albo w plikach INI. Także Ty, w swoich programach możesz wykorzystać rejestr...
Klasa TRegistry
VCL udostępnia nam do tego celu bardzo wygodną w użyciu klasę - TRegistry. Naprawdę, tworzenie kluczy w rejestrze przy pomocy tej klasy jest rzeczą bardzo prostą. Na początek musisz do sekcji uses dodać w swoim programie moduł Registry. A teraz test - stworzenie nowego klucza. Ogólnie przyjętą regułą jest to, że klucze dla aplikacji zapisywane są w kluczu głównym HKEY_CURRENT_USER. My także będziemy tam zapisywali swoje dane.procedure TMainForm.btnAcceptClick(Sender: TObject); var Reg : TRegistry; // deklaruj zmienna dla klasy begin Reg := TRegistry.Create; // stworz zmienna try Reg.OpenKey('SoftwareRegApp', True); // utworz katalog finally Reg.Free; // zwolnij klase end; end;
Taki oto kod spowoduje utworzenie katalogu (klucza) o nazwie RegApp w kluczu: HKEY_CURRENT_USERSoftware. Jak to wszystko się odbywa? Początek do zadeklarowanie zmiennej dla klasy, później następuje utworzenie klasy - to najważniejsze, bez tego program spowoduje błąd Access Violation. Zauważ, że wszystko jest zamknięte w wyjątkach (słowach try..finally ). Ty także tak rób, gdyż ew. błąd i tak spowoduje zwolnienie pamięci przydzielonej dla klasy TRegistry. Procedure OpenKey klasy TRegistry nie tylko otwiera klucz (jak można by się było domyśleć pod nazwie) ale także go tworzy w wypadku, gdy takowy nie istnieje. Decyduje o tym drugi parametr - jeżeli jest to True to taki klucz zostanie utworzony, gdy nie istnieje - jeżeli False - nie zostanie utworzony. Pierwszy parametr, to oczywiście ścieżka, gdzie klucz ostanie otworzony. Możesz to sprawdzić wpisując powyższy kod do swojej aplikacji. Następnie gdy wejdziesz do rejestru w kouczu HKEY_CURRENT_USER/Software zobaczysz katalog RegApp. Bardzo łatwo możesz także tworzyć pod katalogi - po prostu piszesz: Reg.OpenKey('SoftwareRegAppOpcje', True) i już zostanie stworzony pod katalog "Opcje".
Piszemy przykładowy program
W naszym programie wykorzystywać będziemy komponent TMonthCalendar, TEdit oraz TButton. W programie użytkownik będzie mógł wpisać swoje imię oraz datę urodzin. Potem program to "zapamięta" i w przypadku, gdy podana data urodzin równa się dacie dzisiejszej wyświetli okno z życzeniami :)W tym celu należy do rejestru zapisać dwie wartości - datę (typu TDate ) oraz imię (typ: String ). Nie będzie to zbyt trudne. Cała procedura wygląda tak:
procedure TMainForm.btnAcceptClick(Sender: TObject); var Reg : TRegistry; // deklaruj zmienna dla klasy begin Reg := TRegistry.Create; // stworz zmienna try Reg.OpenKey('SoftwareRegApp', True); // utworz katalog Reg.WriteString('Imie', edtName.Text); // zapisz imie Reg.WriteDate('Data', Calendar.Date); // zapisz date finally Reg.Free; // zwolnij klase end; end;
Do zapisywania wartości tekstowych (typu String) służy procedura WriteString. Do zapisywania wartości typu TDate procedura WriteDate. Pierwszym parametrem jest nazwa nowej wartości, która widniała będzie w rejestrze, a druga wartość to właśnie wartość :) danej pozycji. Taki kod spowoduje zapisanie do rejestru kilku ważnych dla programu danych. Nie jest to trudne, prawda? Wszystko leży w kwestii zapamiętaniu kilku poleceń. Odczyt danych z rejestru również nie jest trudny - polecenia praktycznie są takie same, tyle, że zamiast Write pisze się Read.
Wygeneruj procedurę OnCreate formy i wpisz taki kod:
procedure TMainForm.FormCreate(Sender: TObject); var Reg : TRegistry; KeyExists : Boolean; begin Reg := TRegistry.Create; try KeyExists := Reg.OpenKey('SoftwareRegApp', False); // otworz klucz if not KeyExists then begin Calendar.Date := Now; // ustaw dzisijsza date na kalendarzu Exit; // nie rob juz nic... end; edtName.Text := Reg.ReadString('Imie'); // odczytaj imie i przypisz do kontrolki Calendar.Date := Reg.ReadDate('Data'); // odczytaj date i wyswietl w kalendarzu finally Reg.Free; end; end;
Ta procedura jest tylko nieco bardziej skomplikowana, z tego powodu, że sprawdzamy, czy klucz istnieje. Dlaczego? Powód jest prosty. W przypadku, gdy program jest uruchamiany po raz pierwszy, klucz taki nie istnieje, a po próbie odczytu danych wystąpi wyjątek. Funkcja OpenKey zwraca True jeśli klucz istnieje, a False jeżeli nie istnieje. Dzięki temu właśnie możemy sprawdzić, czy program jest uruchamiany po raz pierwszy. Jeżeli więc klucz nie istnieje to do kalendarza przypisana jest data dzisiejsza, a dalsze czynności odczytu nie są już odczytywane. W przeciwnym wypadku dzięki funkcji ReadString oraz ReadDate dane są odczytywane i przypisane do komponentu. Parametr tych funkcji jest jeden - nazwa klucza.
Teraz pozostaje posprzątanie po sobie. Każdy program, który dopisuje coś do rejestru powinien mieć funkcje odinstalowania, w tym także usunięcia niepotrzebnych danych zawartych w rejestrze, gdy nie jest już konieczne ich używanie. Usuwanie klucza jest bardzo proste bo realizuje się za pomocą funkcji DeleteKey.
procedure TMainForm.btnEraseClick(Sender: TObject); var Reg : TRegistry; begin Reg := TRegistry.Create; try Reg.DeleteKey('SoftwareRegApp'); // wykaowanie klucza Application.MessageBox('Klucze zostały prawidłowo usunięte.', 'Sukces', MB_OK + MB_ICONINFORMATION); finally Reg.Free; end; end;
Jak widzisz w nawiasach podana jest ścieżka klucza do usunięcia. Jeżeli chcesz usunąć pojedynczą wartość w kluczu stosujesz DeleteValue.
Teraz już masz podstawowe informacje dotyczące dodawania kluczy do rejestrów. Oto kod źródłowy przykładowego programu:
(****************************************************************) (* *) (* Sample RegApp *) (* Copyright (c) 2001 by Adam Boduch *) (* www.4programmers.net *) (* boduch@poland.com *) (* *) (****************************************************************) unit MainFrm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls; type TMainForm = class(TForm) Calendar: TMonthCalendar; Label1: TLabel; edtName: TEdit; btnAccept: TButton; procedure FormCreate(Sender: TObject); procedure btnAcceptClick(Sender: TObject); end; var MainForm: TMainForm; implementation {$R *.DFM} uses Registry; procedure TMainForm.FormCreate(Sender: TObject); var Reg : TRegistry; KeyExists : Boolean; begin Reg := TRegistry.Create; try KeyExists := Reg.OpenKey('SoftwareRegApp', False); // otworz klucz if not KeyExists then begin Calendar.Date := Now; // ustaw dzisijsza date na kalendarzu Exit; // nie rob juz nic... end; edtName.Text := Reg.ReadString('Imie'); // odczytaj imie i przypisz do kontrolki Calendar.Date := Reg.ReadDate('Data'); // odczytaj date i wyswietl w kalendarzu finally Reg.Free; end; end; procedure TMainForm.btnAcceptClick(Sender: TObject); var Reg : TRegistry; // deklaruj zmienna dla klasy begin Reg := TRegistry.Create; // stworz zmienna try Reg.OpenKey('SoftwareRegApp', True); // utworz katalog Reg.WriteString('Imie', edtName.Text); // zapisz imie Reg.WriteDate('Data', Calendar.Date); // zapisz date finally Reg.Free; // zwolnij klase end; end; procedure TMainForm.btnEraseClick(Sender: TObject); var Reg : TRegistry; begin Reg := TRegistry.Create; try Reg.DeleteKey('SoftwareRegApp'); // wykaowanie klucza Application.MessageBox('Klucze zostały prawidłowo usunięte.', 'Sukces', MB_OK + MB_ICONINFORMATION); finally Reg.Free; end; end; end.
Zwróć uwagę, że otwierając klucz nie musisz podawać klucza głównego, np: HKEY_CURRENT_USER. Program domyślnie dopisuje tam dane. Ty jednak możesz to zmienić jeśli chcesz zapisać swoje dane gdzieś indziej. Klasa TRegistry posiada właściwość RootKey, do której przypisujesz nazw klucza głównego. Oto przykład:
Reg.RootKey := HKEY_CLASSES_ROOT;
Oczywiście przy pomocy klasy TRegistry możesz także zapisywać/odczytywać inne typy zmiennych. Ich nazwy można się łatwo domyśleć. Na przykład, że polecenie zapisujące liczbę Integer to WriteInteger, a odczytujące to ReadInteger.
Oto inne przykłady:
// typ Integer Reg.WriteInteger('WartoscInteger', 12); // zapisana liczba 12 // odczyt typu Integer Edit1.Text := IntToStr( Reg.ReadString('WartoscInteger')); // typ Boolean Reg.WriteBool('WartoscBoolean', True); // zapisana wartość True // odczytanie wartości Boolean: Checkbox1.Checked := Reg.ReadBool( 'WartoscBoolean'); // typ zmienno - przecinkowy Reg.WriteCurrency('WartoscCurrency', 3.12); // zapisanie 3.12 // odczyt wartości Currency: Edit2.Text := CurrToStr( Reg.ReadCurrency('WartoscCurrency')); // zapisz aktualną datę i czas Reg.WriteDateTime('DataIczas', Now); // zapisz aktualną datę i czas // odczytaj datę i czas Edit3.Text := DateTimeToStr( Reg.ReadDateTime('DataIczas')); // odczytaj datę i czas
14 komentarzy
w jaki sposób wykonać kopie całego rejestru lub zaznaczonego głównego klucza np. HKEY_LOCAL_MACHINE ?? :)
Nalezaloby sie zastanowic nad usunieciem tego tekstu... na gorze tego dokumentu dodalem link do aktualnej, rozszerzonej i bardziej rozbudowanej wersji.
mnie takzę się przyda iż teraz wiekszośc programów (wiekszych) :P korzysta własnie z zapisywania do rejestru :P...:D
Ok rozwiązałem problem rejestru typu REG_MULTI_SZ.
Pod tym adresem www.stiopaxxl.webpark.pl/EthernetProfile.zip jest program gdzie stosuje procedury do odczytu i zapisu tego brzydkiego typu.
Pozdrawiam.
ubaff REG_MULTI_SZ to tablica łańcuchów znaków ale jak to dziadostwo odczytać to nie wiem :-)
writeString pozwala zapisac rejest typu \"REG_SZ\"
a jak zapisac typ \"REG_MULTI_SZ\" ??
jak sprawdzić czy istniejeją jakieś dane w wartości jak istanieją to zrob coś else tez cos zrób...
chodzi mi o coś takiego:
Reg:=Tregistry.Create;
Reg.RootKey:=HKEY_CLASSES_ROOT;
Reg.OpenKey('CLSID\{D27CDB6E-AE6D-11cf-96B8-444553540000}\MiscStatus\1', true);
if Reg.ValueExists('', '131473') then
CheckBox12.Checked:=false
else
CheckBox12.Checked:=true;
bardzo proszę o pomoc na maila: adsoft(at)gazeta(dot)pl
1. Ma sprawdzić wartość '' (to akurat jest wartośc domyślna)
2. Ma sprawdzić dane w Wartości Domyślnej - czyli jeśli to: '131473' istnieje to zrob to else tamto...
brakuje jeszcze tylko Reg.WriteBinaryData a tego wlasnie mi trzeba... :(
Aby dodac wartosc hex to
var r:tregistry;
tablica:array of char;
linia:string;
i, j:integer;
begin
linia := ':00,00,00,00,00,00,10,40';
SetLength(tablica, length(linia) div 3);
i:=0;
j:=2;
while j<=length(linia) do begin
tablica[i]:=chr(strtoint('$'+linia[j]+linia[j+1]));
j:=j+3;
inc(i);
end;
r:=tregistry.Create;
r.RootKey:=HKEY_CURRENT_USER;
r.OpenKey('Software\cos',true);
r.WriteBinaryData('cos',tablica[0],length(tablica));
r.CloseKey;
r.Free;
end;