![]() |
Angemeldeten Benutzer aus Dienst ermitteln
Hi DP,
ich habe eine Frage, und zwar wie kann ich den aktuell angemeldeten Benutzer ermitteln? Ich habe schon im Forum gesucht, und dort wurde die Variable "username" empfohlen. Ich habe das eingebaut, und als Anwendung funzt es, aber in einem Dienst bekomme ich nur einen Leerstring. MfG xZise [edit=SirThornberry]Titel korrigiert - Mfg, SirThornberry[/edit] |
Re: Angemeldeter Benutzer aus Dienst ermitteln
|
Re: Angemeldeter Benutzer aus Dienst ermitteln
Leider kann ich kein C++ ;)
|
Re: Angemeldeter Benutzer aus Dienst ermitteln
Da gibt es nicht viel C zu können. Die API-Funktionen sind die gleichen.
|
Re: Angemeldeter Benutzer aus Dienst ermitteln
Lustige Sache:
Es können mehrere Benutzer gleichzeit angemeldet sein :D mit den Notification, wie es in dem C++ Artikel auf codeproject gezeigt wird, kann man nur dann reagieren, wenn der Dienst schon von anfang an gestartet ist - sonst bekommt man keine Nachricht. Am einfachsten geht es, wenn man WTSQueryUserToken aus der JWSCL verwendet. Man kann bestimmen, welche Session (lokal, remote) verwendet werden soll und mit dem Token hat soviele Infos über dem Benutzer (Name, SID, usw), dass es reichen sollte. Man kann sogar den Userkontext übernehmen und als Dienst unter diesem Benutzer lustige Dinge machen. |
Re: Angemeldeter Benutzer aus Dienst ermitteln
So... Ich habe nun versucht das zu übersetzen, aber es gibt mehrere Probleme:
Delphi-Quellcode:
library logonoffdll;
const g_szPath : array of PChar =('c:\somepath\execut.exe \"arguments\"'); uses SysUtils, Classes, Windows; {$R *.res} function LinMain(hInst : hInstance; dwReas : DWord; lpReserved : LPVoid) : Boolean; var g_pi : PROCESS_INFORMATION; begin if dwReas = DLL_PROCESS_ATTACH then DisableThreadLibraryCalls(hInst); Result := true; end; procedure StartProcessAtWinLogon(pInfo : PWLX_NOTIFICATION_INFO); var si : STARTUPINFO; begin si.cb := sizeof(STARTUPINFO); si.lpReserved := nil; si.lpTitle := nil; si.lpDesktop := 'WinSta0\\Default'; si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L; si.dwFlags := 0;; si.wShowWindow := SW_SHOW; si.lpReserved2 := NULL; si.cbReserved2 := 0; CreateProcess(NULL, g_szPath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &g_pi); end; procedure StopProcessAtWinLogoff(pInfo : PWLX_NOTIFICATION_INFO); begin SafeTerminateProcess(g_pi.hProcess, 0xDEADBEEF); end; procedure YOUR_EVENT_HANDLERS (pInfo : PWLX_NOTIFICATION_INFO); begin // ??? end; export StartProcessAtWinLogon, StopProcessAtWinLogoff; begin end.
Zitat:
Zitat:
Zitat:
[edit]Ich verzweifle :( Ich habe die Unit gedownloadet, aber mehr auch nicht, weil ich kein einziges Beispiel kompilieren kann, weil die Datei JwaWinType.pas von einen andere Prozess verwendet wird (jedenfalls sagt das TD-E). Also kann ich nicht JwaWindows.pas komplieren, und damit nicht whoami (was wahrscheinlich das Beispiel dazu ist?). Warum es nicht geht: kA :( Ich weiß nur, dass ich sie öffnen konnte, bevor Delphi zu der Zeile {$I JwaWinType.pas} kam... TD-E eben ^^ irrational ...[/edit] MfG xZise |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Zitat:
Guck mal bei ![]() P.S. Wenn du so eine Meldung per Edit einfügst, wird niemand benachrichtigt und es ist nur Zufall, wenn man deinen Post liest. |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Zitat:
Zitat:
MfG xZise PS: Kann man irgendwie ein Dienst schnell testen? Also ohne die ganzen Reboots? |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Zitat:
Wenn du etwas schreiben willst, dann kannste ja gleich einen neuen Post machen, statt zu pushen. Edits sollten eh nur für Kleinigkeiten sein. |
Re: Angemeldeter Benutzer aus Dienst ermitteln
So... Dienst installiert, gestartet und getestet mit folgenden Code:
Delphi-Quellcode:
Ergebnis: Administratoren
function GetUserName : string;
var sl : TStringList; Token : TJwSecurityToken; begin Token := TJwSecurityToken.CreateTokenEffective(TOKEN_READ); try Result := Token.TokenOwner.AccountName['']; finally Token.Free; end; end; Auch wenn keine Admins/niemand angemeldet sind. Habe ich die falsche Variable genommen? MfG xZise [edit]
Delphi-Quellcode:
Was soll ich da übergeben :)[/edit]
JwaWtsApi32.WTSQueryUserToken(????);
|
Re: Angemeldeter Benutzer aus Dienst ermitteln
Zitat:
Du musst das Token des angemeldeten Benutzers verwenden. CreateTokenEffective versucht zuerst das Token des aktuellen Threads zu holen, und wenn das (meist) fehlschlägt, dann des Prozesses. Dazu gibt es den Konstruktor TJwSecurityToken.CreateWTSQueryUserToken Zitat:
Vor einer Frage immer die Hilfe zu den Methoden lesen. Dazu ist sie ja da! |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Zitat:
Ich habe übrigens die Hilfe-Datei durchforstet, und alle Ergebnisse auf "logged, on, user" hängen mit den aktuellen Thread/Process zusammen... Außer WTSQueryUserToken, welches ja nicht unter W2k geht :( MfG xZise |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Zitat:
Siehe in diesem Thread: ![]() Oder eben das angesprochene "session change notification" verwenden. |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Ich hab den Link in die SecLib implementiert:
JwsclToken.TJWSecurityToken:
Delphi-Quellcode:
{@Name is a compatibility constructor for CreateWTSQueryUserToken which does
not work in Windows 2000. It creates a token of the current logged on user. This constructor seeks a process of the user and gets its token. It only works in the same (terminal) session of the process. @param(DesiredAccess defines the desired access to the token) @param(ProcessName defines which process is used to get the token of the user) @raises(EJwsclProcessNotFound will be raised if process handle given in parameter ProcessName could not be retrieved.) @raises(EJwsclWinCallFailedException will be raised if the process handle of the found process could not be opened) @raises(EJwsclSecurityException Several exceptions can be raised by used methods: @unorderedlist( @item(CreateTokenByProcess) @item(CreateDuplicateExistingToken) )) } constructor CreateCompatibilityQueryUserToken( const DesiredAccess: TJwAccessMask; const ProcessName : TJwString = ExplorerProcessName); |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Und wo finde ich den Aufruf?
Ich habe mir die neueste Version gedwonloadet ohne Erflogh! |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Diese Version ist aktuell nur über SVN erreichbar. Du kannst aber Uptodate werden, wenn du mit SVN ein update von dem Heruntergeladenen Quellen machst.
Am einfachsten geht es mit dem WindowsProgramm TortoiseSVN und dann einfach rechtsklick auf JWSCL und JWAPI und dann Aktualisieren. |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Alles klar :) Ich hatte angenommen, dass auch das andere aktualisiert wird.
Ich werde morgen mal gucken. Ggf. fällt eine Lehrerin aus, so dass ich 'ne Freistunde hätte. MfG xZise |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Also ich hab nicht rausgefunden, wie man bei SF sogenannte Daily-Builds erstellen kann - wenn das überhaupt möglich ist.
|
Re: Angemeldeter Benutzer aus Dienst ermitteln
So... ich mache dass jetzt über das neue, aber er kann den nicht installieren:
Zitat:
|
Re: Angemeldeter Benutzer aus Dienst ermitteln
Wenn du kein Vista-Funktionalität verwenden willst, kannst du in Jwscl.inc die Direktive {$DEFINE VISTA} ausschalten (nach {.$DEFINE VISTA}). Nur möglich ab Revision #71.
Wenn du Vista-Funktionalität haben willst, und dein Programm nur auf Vista und neuer laufen soll, dann kannst du die Jedi Window API (Jwa) mit STATIC kompilieren -> Compiler Direktive: DYNAMIC_LINK ausschalten. Das geht entweder in JwaWindows.pas oder in Projektoptionen. Lese dazu die JwaWindows.pas Wenn du Vista-Funktionalität haben willst, und dein Programm auch unter älteren OS laufen soll, dann musst du die JEDI Windows API (Jwa) mit DYNAMIC_LINK kompilieren -> Compiler Direktive: DYNAMIC_LINK einschalten. Das geht entweder in JwaWindows.pas oder in Projektoptionen. Lese dazu die JwaWindows.pas Ich empfehle immer die Pakete der JWA zu verwenden!! Sie sind unter \jedi-api-lib\jwapi\trunk\Packages\XXX z.b für BDS10 \jedi-api-lib\jwapi\trunk\Packages\bds10\JediApi_Bds10.bdsgr oup Da kannst du einfach beliebige Versionen (Debug, Release, Dynamic, Static) erstellen. Das einzige was du dazu machen musst ist im Projekt oder in den Delphiglobalen-Bibliothekspfade den absoluten Pfad zu den DCU Dateien einzufügen. z.b. jedi-api-lib\jwapi\trunk\Packages\bds10\bin\debug\dynamic Wenn Änderungen in der JWA stattgefunden haben, muss man die Pakete neu kompilieren. Ich glaube, dass hab ich schon mal vorher beschrieben. |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Okay :(
Aber er kompliert nur JwaWindows und JwaVista. Aber ich benötige wegen den Tokens andere dcus. MfG xZise |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Zitat:
Um z.b. Token nutzen zu können verwendest du die Unit JwsclToken, die in "...\jedi-api-lib\jwscl\trunk\source" liegt. Diesen Pfad kannst du auch in den globalen Suchpfad von Delphi eintragen. Im Gegensatz zur JWA verwendet die JWSCL keine Pakete, da es sich hier nicht lohnt DCU Dateien zu verwenden. Sie wird einfach zu oft aktualisiert. |
Re: Angemeldeter Benutzer aus Dienst ermitteln
Hmmm....
Er gibt eine Fehlermeldung aus, dass der Explorer.exe Prozess nicht gefunden wurde. Natürlich gibt es den nicht als Starter des Dienstes, aber wenn ich das Aufrufe gibt es eine Explorer.exe ;) MfG xZise |
DP-Maintenance
Dieses Thema wurde von "SirThornberry" von "Object-Pascal / Delphi-Language" nach "Windows API / MS.NET Framework API" verschoben.
|
Re: Angemeldeten Benutzer aus Dienst ermitteln
Ich verstehe nicht, warum das ein Problem der JWSCL sein soll?!
|
Re: Angemeldeten Benutzer aus Dienst ermitteln
Naja? Wenn ich das Token "lade", bekomme ich den Fehler dass keine Explorer.exe gestartet ist?
Allerdings ist dem nicht so ... Also weiß ich nicht, warum die JWSCL einen Fehler wirft und deshalb kein Ergebnis liefert. MfG xZise |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Axo jetzt verstehe ich. Du verwendest CreateCompatibilityQueryUserToken .
Natürlich gibt es kein Explorer.exe, wenn kein Benutzer eingeloggt ist, oder dein Dienst sich nicht in der Session eines angemeldeten Benutzers liegt. Du kannst es natürlich mit try/except abfangen. Viele Methoden werfen Exceptions. |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Zitat:
Zitat:
Oder könnte man die Tokens der Explorer.exe herausfinden? Weil unter Windows 2000 konnte sich ja nur ein Benutzer anmelden... MfG xZise PS: Läuft die Explorer.exe eigentlich auch, wenn niemand angemeldet ist? |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Zitat:
Zitat:
Zitat:
Er schlägt natürlich fehl, wenn keiner eingeloggt ist, weil dann der Explorer.exe Prozess nicht existiert. Du kannst erst dann das UserToken unter Win2000 bekommen, wenn ein Benutzer sich angemeldet hat und Explorer.exe existiert. Für WindowsXP/2003 und neuer verwende auf jeden Fall den Konstruktor CreateWTSQueryUserToken. |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Zitat:
Zitat:
Zitat:
Also folgern wir daraus, dass ein installierter Dienst unter Windows 2000 mithilfe von CreateCompatibilityQueryUserToken nicht den (?) Token des angemeldeten Benutzers herausfinden kann? Mensch ist das geil xD Gerade das Betriebssystem, welches nur einen Benutzer unterstützt, kann nicht den Benutzernamen oder Adminrechte zurückgeben? Da sollte es doch besser funktionieren, weil es nur einen geben kann, also es nur 2 Fälle gibt: Angemeldet/Abgemeldet MfG xZise |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Nein, du bist mit deinen Gedanken weit von der Erde entfernt, wo das Problem liegt :angel:
Es wurde einfach in der Groß-Kleinschreibung unterschieden. Das ist aber bei Prozessnamen egal. :wall: Wenn du Update machst, sollte es funktionieren. :cheers: |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Zitat:
Zitat:
Also es lässt sich nun kompilieren und ausführen. Und er scheint auch einen Benutzernamen zu bekommen ;) Habe leider es nur nicht in der Aufregung getestet :oops: Wird Freitag wahrscheinlich erst was xD MfG xZise |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Hallo,
ich wollte gerade mal meinen Serivce wieder testen und auf Vordermann bringen, und dann habe ich das Problem, das die JWSCL meint, es gäbe die "Explorer.exe" nicht:
Delphi-Quellcode:
Obwohl ich eindeutig jetzt mit den Rechner schreibe, und wie man sieht :) Es funktioniert, mit Explorer.exe!
An Exception of type EJwsclProcessNotFound was raised.
(Data was given by programmer and can vary from actual source.) Source method....: CreateCompatibilityQueryUserToken Source class.....: TJwSecurityToken Source file......: JwsclToken.pas Source line......: 0 Message : The process "EXPLORER.EXE" could not be found. MfG xZise |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Ich vermute mal, dass CreateToolHelp32SnapShot nicht alle Prozesse von allen Sessions auflistet.
Du kannst ![]() EDIT: In der Tat, es handelt sich bei der CreateCompatibilityQueryUserToken um eine Funktion, die nur für WindowsNT, 2000 und XP überhaupt funktioniert und dann auch nur für den ersten eingeloggten Benutzer, weil dieser eben in derselben Session des Dienstes (Session 0) sich befindet. Alles andere funktioniert nicht. |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Es war ganz einfach (vermute ich): Da ich die falschen Quellen genommen habe, funktionierte das auch dann nicht, wenn einer angemeldet ist. Ansonsten ist mir das egal ;)
MfG xZise |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Zitat:
|
Re: Angemeldeten Benutzer aus Dienst ermitteln
Also:
Es gibt verschiedene Stadien:
Im zweiten hingegen sucht JWSCL nach "Explorer.exe", welches es aber nicht findet bzw. finden kann, also ist die Fehlermeldung angebracht (oder geht das auch "netter"?). Und im letzten Stadium erkennt die JWSCL die "Explorer.exe" und kann dessen Benutzer einwandfrei ausgeben :) MfG xZise |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Ich habe dieses Artikel mal darüber geschrieben.
![]() |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Hallo,
also ich verwende inzwischen folgenden Code:
Delphi-Quellcode:
Und bei dem Aufruf von „TJwSecurityToken.CreateWTSQueryUserToken(TOKEN_AL L_ACCESS);“ bekomme ich dann folgenen Fehlertext:
function GetUserName : string;
var Token : TJWSecurityToken; begin Token := TJwSecurityToken.CreateWTSQueryUserToken(TOKEN_ALL_ACCESS); try try Result := Token.TokenOwner.AccountName['']; AddToLog('Username requested: ' + Result); except on e : Exception do begin AddToLog('@GetUsername' + #13#10 + e.Message); Result := ''; end; on e : EJWSCLProcessNotFound do begin AddToLog('No user is loged on'); Result := ''; end; end; finally Token.Free; end; end; Zitat:
xZise |
Re: Angemeldeten Benutzer aus Dienst ermitteln
Zitat:
Fragen: 1. Wird die Funktion aufgerufen, wenn kein Benutzer angemeldet ist? 2. Welche Windows Version verwendest du? 3. Welche JWSCL Version verwendest du (0.9.2a?) und welche Updateversion (=Subversion revision) hast du (wenn du das nicht weißt, dann genügt mit das auch)? --
Delphi-Quellcode:
TokenOwner ist der Besitzer des Tokens - das ist meist "Administratoren". Was du suchst ist das Property TokenUser.
Result := Token.TokenOwner.AccountName[''];
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz