Berücksichtigung von Benutzerrechten
Als Administrator
Wenn ein Normalanwender doch einmal Zugriff auf HKEY_LOCAL_MACHINE oder ein Verzeichnis im Dateisystem braucht, auf das er normalerweise kein Zugriff hat, muss man zwischenzeitlich den Benutzerkontext wechseln.
Wir starten folgenden Versuch: Wir erstellen eine Anwendung, die nur einen einzelnen Button enthält. Das onClick-Ereignis dieses Buttons schreibt eine Text-Datei direkt nach C:\ – was man unter Windows 7 nur mit Administratorrechten darf.
Der Code sieht so aus:
procedure TForm1.Button1Click(Sender: TObject); var sl: TStringList; begin sl := TStringList.Create; try sl.Add('Hallo Welt!'); sl.SaveToFile('C:\hallowelt.txt'); finally sl.Free; end; end;
Wenn wir das Programm mit normalen Benutzerrechten starten (nicht als Administrator!) und auf den Button klicken, erhalten wir eine Fehlermeldung:
Diese Meldung ist prinzipiell richtig. Der Benutzer hat schließlich keine Schreibrechte. Aber nun wollen wir, dass Windows den Benutzer nach dem Administrator-Passwort fragt, um die Datei dennoch anlegen zu können.
Diese Rechteerweiterung (im Englischen spricht man von „elevate“) ist unter Windows nur für neue Prozesse möglich. Man muss also bei Klick auf den Button einen neuen Prozess (eine DLL oder eine EXE) starten und dieser mitteilen, dass sie Administratorrechte benötigt. Dann sorgt Windows selbst dafür, nach dem Passwort zu fragen.
Um einer Anwendung zu sagen, dass sie nur mit Administratorrechten läuft, muss ihr ein Manifest beigefügt werden. Dabei handelt es sich um eine XML-Datei mit folgendem Inhalt:
elevate execution level
Zu beachten sind hier die Zeilen 6 bis 10, die das Vorhandensein von Administratorrechten fordern.
Diese XML-Datei muss nun als Ressource kompiliert und in die Anwendung eingebunden werden. Eine Anleitung dazu findet sich in der Delphi-Praxis.
Eine ausführliche Anleitung, wie man die JEDI Windows Security Code Lib für diese Zwecke verwenden kann, findet sich im JEDI-Blog.
Und auch von Microsoft gibt es eine Anleitung zu diesem Thema, natürlich nicht auf Delphi bezogen.