Problem beim Zugriff auf die Registry in einer ServiceAnwendung
-
Hi
Ich programmiere z.Z. einen Service mit TurboC++ (BDS 4.0) und versuche in diesem auf die Registry zuzugreifen. Das sieht wie folgt aus:
HKEY hKey; byte *out=NULL; unsigned long size=1; int err=RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\MSNMessenger", 0,KEY_ALL_ACCESS,&hKey); if(hKey==NULL) ShowMessage("err:"+IntToStr(err)); ShowMessage("GetLastError:"+IntToStr(GetLastError())); do { delete out; out=new byte[size]; } while(RegQueryValueEx(hKey,"AppCompatCanary",NULL,NULL,out,&size)==ERROR_MORE_DATA); RegCloseKey(hKey);Das Problem ist, dass hKey immer NULL ist. Also habe ich die zwei Messages eingebaut um mir anzugucken woran das liegen könnte.
Die erste sagt folgendes: 2: ERROR_FILE_NOT_FOUND
Das komische ist nur, dass der genau selbe Quelltext (copy&paste) in einer VCL-Anwendung einen gültigen Key und Error_Succes zurückgibt
Der Key existiert auch definitiv.Die zweite MessageBox sagt dann folgendes: 299: ERROR_PARTIAL_COPY
Darauf kann ich mir keinen Reim machen
Hat einer eine Idee warum es in einer VCL-Anwendung geht aber in einem Dienst nicht?
Bin für jede Hilfe dankbar.Gruß
rean
-
Der C++Builder hat extra eine Klasse für die Registry (TRegistry). Die Frage wäre im WIN API Forum besser
-
Ich weis aber ich finde die WinApi-Funktionen schlanker und die Möglichkeiten zur Fehlerauswertung besser.
Außerdem kriege ich bei der Verwendung von TRegistry nur ein einfaches false von OpenKey zurück.
Und es gehört deswegen nicht ins WinApi-Forum weil es sich offensichtlich um ein Problem von TServiceApplication handelt da es bei einer normalen VCL-Anwendung ja einwandfrei funktioniert.
-
nach meiner Erfahrung mit einigen Diensten geht das auch mit TRegistry in einem TService nur begrenzt,
man kann nur auf Schlüssel des Dienstes zugreifen und die liegen alle unter HKEY_LOCAL_MACHINE, alle Versuche auf HKEY_CURRENT_USER zuzugreifen schlugen bisher fehldeshalb ist das Thema hier nicht ganz falsch
und eine Lösung würde mich auch interessieren
-
Ok noch ein paar Infos:
Die Routine liegt in einem OnTimer-Event.
Der Timer ist standardmässig deaktiviert und wird im ServiceStart-Event meines Services aktiviert damit sein Event nicht schon bei der Installation sondern erst beim Starten des Dienstes ausgeführt wird.
Wenn ich den Timer jetzt standardmässig aktiviere kriege ich Error_Succes für RegOpenKeyEx
Das wirklich seltsame ist, dass der Timer auch schon vorher korrekt aktiviert wurde. Ich hab ja auch schon vorher die Messages gesehen...
Jetzt kriege ich wie gesagt Error_Succes bei RegOpenKeyEx dafür aber ERROR_FILE_NOT_FOUND bei RegQueryValueEx *sigh*
-
Wie heißt es doch so schön?
Manchmal sieht man den Wald vor lauter Bäumen nicht.Unter dem Rootkey 'Current_User' sind, wie der Name schon sagt, die Schlüssel für den momentan angemeldeten Benutzer gespeichert, bzw. sind die Schlüssel dort nur so etwas wie Links zum eigentlichen Speicherort unter 'Users'.
Dienste werden aber nicht vom aktuellen Benutzer gestartet sondern unter dem Konto 'System', wie man auch im Taskmanager sehen kann.
Das heißt, dass das Current_User Verzeichnis auf das der Dienst zugreifen kann praktisch das vom Konto 'System' ist. Das auf das man über Regedit zugreift aber das vom aktuell angemeldeten Benutzer.Ich hoffe ich drücke mich einigermassen verständlich aus

Die Quintessenz ist: Current_User sieht für einen Dienst anders aus als für den angemeldeten Benutzer.Zu den einzelnen Verhältnissen siehe hier: http://support.microsoft.com/kb/q163846/
Lösung des Problems ist es einfach auf die entsprechenden Schlüssel unter HKEY_USERS\S-1-5-21-xxx zuzugreifen.
Diese scheinen ohnehin die "Originale" zu sein. Die Schlüssel unter Current_User sind wie schon erwähnt offensichtlich nur so etwas wie Links zu dieser Position.Es ist allerdings ein gewisses Problem herauszufinden welcher der Schlüssel unter HKEY_USERS der passende zum angemeldeten User ist. GetUserName liefert in einem Dienst immer 'System' zurück und selbst wenn man den Benutzernamen kennt weis ich nicht wie man davon auf den entsprechenden Schlüssel in Users schließt.
Alle Schlüssel unter Users sind an dieser Position gespeichert: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
Allerdings ohne Indizien dafür zu enthalten welcher der Schlüssel zu welchem Benutzer gehört. Das einzige wäre der Wert: ProfileImagePath der das hier enthält: %SystemDrive%\Dokumente und Einstellungen\Test
Allerdings bin ich mir nicht sicher ob in diesem Wert immer der Benutzername am Schluss vorkommen muss.
Außerdem bleibt dann immernoch das Problem herauszufinden welcher Benutzer aktuell angemeldet ist.Ich hoffe das was ich hier geschrieben habe ist verständlich. Außerdem entschuldige ich mich für den Doppelpost aber der Thread ist schon so abgerutscht, dass wohl niemand diese Antwort in einem Edit gelesen hätte.
Vielleicht fällt ja noch jemandem ein wie man den angemeldeten Benutzer in einem Dienst bestimmt. Die ganzen StandardWinapis hab ich schon durchprobiert (GetUserName etc.).
Jedenfalls geh ich jetzt schlafen.
hf & cu
-
rean schrieb:
Vielleicht fällt ja noch jemandem ein wie man den angemeldeten Benutzer in einem Dienst bestimmt.
wenn der Dienst beim Rechnerneustart automatisch gestartet wird, muß niemand angemeldet sein, insofern nützt es nichts einen Benutzer zu suchen
günstiger wär wahrscheinlich alle Schlüssel aus ProfileList zu nehmen und dann in HKEY_USERS diese Schlüssel nach dem gesuchten Wert abzusuchen, wobei man alle die Schlüssel ignorieren kann, die keine ProfileImagePath gesetzt haben
ausserdem scheint es so zu sein, dass nicht für alle User Schlüssel in HKEY_USERS vorhanden sind
rean schrieb:
Das einzige wäre der Wert: ProfileImagePath der das hier enthält: %SystemDrive%\Dokumente und Einstellungen\Test
Allerdings bin ich mir nicht sicher ob in diesem Wert immer der Benutzername am Schluss vorkommen muss.bei meinem Rechner ist immer dann der Benutzername am Ende angegeben, wenn der Wert für ProfileImagePath gesetzt ist