Werfen wir doch mal einen Blick auf das Beispielprogramm.
Was macht es?
Es liest die Displaynamen und die Uninstall-Strings der installierten Programme aus. So weit, so gut. Zusätzlich liest es aber auch die versteckten Komponenten, die nicht in der Systemsteuerung zu sehen sind, und deren Registryeinträge "QuietDisplayName" und "QuietUninstallString" lauten. Das ist das ganze Geheimnis! Deswegen zeigt Ihnen das Programm auch mehr an als Ihre Systemsteuerung.
Diese Fähigkeit des Systems können wir nutzen. Wenn Sie z.B. den Displaynamen einer Software löschen, verschwindet der Eintrag aus der Systemsteuerung, obwohl die Software natürlich noch vorhanden ist und deinstalliert werden kann. Das ist übrigens auch die zweite Aufgabe des Programms. Sie können nicht nur den Displaynamen (beide; den bekannten und den versteckten) nach Belieben ändern und so Ihre Liste vergrößern oder verkleinern, Sie können Programme auch direkt deinstallieren lassen.
Mir ist es schon einmal passiert, dass ich in der Systemsteuerung den falschen Eintrag angeklickt und damit die falsche Software entfernt habe. Seitdem nutze ich das Programm bevorzugt, um die Dinge zu verbergen, die man nicht versehentlich entfernen können soll.
Gut. Nach der Werbung für meine Software wollen wir uns nun wieder auf das Wesentliche konzentrieren. ;o)
Die Überschrift bringt es bereits auf den Punkt: um Werte in die Registry schreiben zu können, genügt KEY_READ nicht mehr. Erschwerend kommt hier noch dazu, dass wir in den Schlüssel HKEY_LOCAL_MACHINE schreiben müssen.
Ich erwähnte ja bereits die Frage der Rechte bei NT-Betriebssystemen (Windows NT, 2000, XP). Das Beispielprogramm ist so gestaltet, dass es diese Funktionalität nur anbietet, wenn es von einem Benutzer mit Administratorrechten gestartet wurde. Andernfalls sind die Toolbar-Buttons z.B. deaktiviert, usw. Nun könnten Sie zwar den Quellcode entsprechend ändern, aber ich möchte davon abraten. Es bringt nichts; bestenfalls sehen Sie ein paar Fehlermeldungen, aber Abstürze oder Schäden an der Registry wären ebenso denkbar ...
Setzen wir also voraus, dass wir die notwendigen Rechte seitens des Betriebssystems haben. Nun öffnen wir den Registryschlüssel mit dem zusätzlichen Recht KEY_WRITE
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar(szUnInst + '\' + buffer),0, KEY_READ or KEY_WRITE,rgHandle) = ERROR_SUCCESS) then try { ... } finally RegCloseKey(rgHandle); end;
Der Pfad ergibt sich in dem Fall aus dem Standardpfad der installierten Software (in der Konstante szUnInst) und dem ausgewählten Eintrag der List-View.
Bleiben wir beim Displaynamen -
Im Beispiel wird er aus dem Dialog gelesen, den das Programm bereitstellt. Gehen wir davon aus, dass der Anwender einen neuen Wert eingetragen hat. Dann rufen wir nun die Funktion
RegSetValueEx(rgHandle,
Es folgt der Name, den wir eintragen oder ändern wollen
'DisplayName',
Der nächste Parameter ist reserviert und muss daher Null sein
0,
Es folgt der Typ unseres Wertes. Da wir einen String eintragen wollen, benutzen wir
REG_SZ,
Der nächste Parameter ist ein Zeiger auf den Puffer, der den Inhalt unseres Eintrags enthält. Da wir hier einen String verwenden, verweisen wir auf das erste Zeichen (denn im 0. Zeichen des Strings befindet sich dessen Länge)
@dn[1],
Der letzte Parameter ist die Größe des Puffers; die Stringlänge plus 1 in unserem Fall
length(dn)+1)
Ich habe es mir hier ein wenig einfach gemacht und nur den Funktionsaufruf demonstriert. Im Programm findet natürlich eine Prüfung statt, ob der Aufruf auch erfolgreich war. Sie sollten dies ebenfalls nicht vernachlässigen.
Um einen Eintrag zu löschen, benötigen wir lediglich unseren geöffneten Schlüssel. Das Beispielprogramm demonstriert Ihnen die Vorgehensweise: wenn die Variable "dn" der Konstante szUnknown ("[unbekannt]") entspricht, wird sie auf Null zurückgesetzt. Ist der String leer (weil im Dialog nur der Eintrag entfernt und nicht durch einen neuen ersetzt wurde), ist dies natürlich nicht erforderlich. Das Programm prüft dann ob die Variable leer ist und entfernt in diesem Fall den Eintrag mit der Funktion
if(dn = '') then iRes := RegDeleteValue(rgHandle,'DisplayName') { ... }
Die Syntax der Funktion ist also recht einfach.
Kommen wir noch einmal auf den hier angesprochenen Autostart-Eintrag zurück, der entweder binär oder als dword gespeichert wird.
Die eben beschriebene Vorgehensweise ändert sich auch hier nicht. Anstelle des Zeigers auf einen String, benutzen wir hier einen Zeiger auf unsere dword-Variable. Als Größe übergeben wir den Größenwert eines dword, bzw. den Größenwert der von uns benutzten Variable. Und der Typ entscheidet, in welchem Format der Wert gespeichert wird.
Beispiel A: wir speichern den Autostart-Eintrag für Windows 98 im binären Format:
RegSetValueEx(rgHandle, 'NoDriveTypeAutoRun', 0, REG_BINARY, @AutorunSettings, sizeof(AutorunSettings));
Beispiel B: wir speichern den Eintrag nun als dword. Es ist alles identisch, nur der Typ ist ein anderer:
RegSetValueEx(rgHandle, 'NoDriveTypeAutoRun', 0, REG_DWORD, @AutorunSettings, sizeof(AutorunSettings));
Was würde passieren, wenn wir unseren String im binären Format speichern? Um Ärger zu vermeiden verwenden wir aber einen anderen Namen:
RegSetValueEx(rgHandle,'BinaryDisplayName',0, REG_BINARY,@dn[1],length(dn)+1);
Wie gesagt: "dn" ist eigentlich eine String-Variable, aber das Ergebnis sieht im Registry-Editor so aus:

Es klappt also. Dennoch möchte ich davon abraten, wild mit den Formaten zu jonglieren. In dem Fall mag es funktionieren, weil man einen String ja durchaus in dieser binären Form ablegen kann; in anderen Fällen kann es Fehler geben, mehr oder weniger schwerwiegend ... aber stets unschön ...