Rejestry systemu Windows
Adam Boduch
Uwaga! Wersja skrócona.
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
Aby dodac wartosc hex to
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" ??
"Rejestry" są w procesorach, a nie w W$ :-D
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
Hmm OK ale jak wstawić Klucz DWORD ???
brakuje jeszcze tylko Reg.WriteBinaryData a tego wlasnie mi trzeba... :(
Boski artykuł na pewno się przyda :D:D:D
regedit a nie regEdit i nie registry.
chyba pisze się regEdit a nie registry :-)