Announcement

Collapse
No announcement yet.

getUserName oder ähnliches aus Service

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • getUserName oder ähnliches aus Service

    Wieder dieser Capiservice...
    Ich möchte aus einem Service Heraus mitbekommen, wenn sich entweder ein benutzer abmeldet oder die Arbeitsstation sperrt und umgekehrt, das anmelden / entsperren, für das Erkennen der sperrung habe ich noch gar keine Idee und da getUserName (logischerweise) bei Aufruf aus einem Service immer 'SYSTEM' zurückgibt fehlt mir eigentlich auch noch eine Idee für das an/abmelden

  • #2
    Deine Frage zum eingeloggten Benutzer wird in der MSDN ( http://msdn.microsoft.com/library/en-us/winui/winsta_4ied.asp ) beantwortet.

    Um Festzustellen, ob sich gerade ein Benutzer an-/abmeldet wird eigentlich WM_ENDSESSION verwendet, da Dein Service aber nicht interaktiv zu sein scheint und wohl kaum ein fenster benötigt, dürfte die Nachricht nicht beim Service ankommen.<br>
    Zudem wird dadurch nicht der Fall abgedeckt, daß der User die Window-Station sperrt.<br>
    (leider kenne ich nur einen undokumentierten Weg, den Desktop-Wechsel innerhalb einer Window-Station zu triggern, sorry)

    Gruß Nic

    Comment


    • #3
      ob Dokumentiert oder nicht ist mir relativ egal, solange ich dadurch nicht das sytem aus dem tritt bringe
      <p>
      Das Sperren der Station ist doch auch ein Desktopwechsel, da mir ja völlig egal ist, wer grade angemeldet ist oder nicht, bräuchte ich also nur eine Funktion die mir sozusagen den Logonstate zurückgibt,
      so wie im MSDN diese Sates beschrieben sind: "Logged Out", "Logged In", "Workstation Locked", wenn ich das dann alle paar sekunden abfrage habe ich alles was ich brauche (bis auf den Bildschirmschoner aber das ist ja eine andere Diskussion )

      Comment


      • #4
        Oder kann man abfragen, welcher Desktop aktiv ist? Dann bräuchte ich aber (bzgl. des Schoners) auf jeden Fall eine zuverlässigere Möglichkeit als SetKeyboardState um Num-Lock etc. zu setzen ohne einen Tastaturevent auszulösen!
        <P>
        Ach so, Apropos undokumentiert, wenn Dir das lieber ist, nehme ich einen Tip auch gerne unter <a href="mailto:[email protected]" >mailto:[email protected]</a> an...
        &#10

        Comment


        • #5
          Erstmal ein paar Deklarationen für Delphi...

          <pre><p><i>////////////////////////////////////////////////////////////////////////////////
          //
          // Some NT types and constants
          //
          ////////////////////////////////////////////////////////////////////////////////</i>
          <p>
          <b>type</b>
          NTSTATUS = Integer;
          <p>
          <b>const</b>
          STATUS_SUCCESS = NTSTATUS(0);
          STATUS_ACCESS_DENIED = NTSTATUS($C0000022);
          <p>
          <b>type</b>
          PUnicodeString = ^TUnicodeString;
          TUnicodeString = <b>packed record</b>
          Length : Word;
          MaximumLength: Word;
          Buffer : PWideChar;
          <b>end</b>;
          <p>
          <b>const</b>
          OBJ_INHERIT = $00000002;
          OBJ_PERMANENT = $00000010;
          OBJ_EXCLUSIVE = $00000020;
          OBJ_CASE_INSENSITIVE = $00000040;
          OBJ_OPENIF = $00000080;
          OBJ_OPENLINK = $00000100;
          OBJ_KERNEL_HANDLE = $00000200;
          OBJ_VALID_ATTRIBUTES = $000003F2;
          <p>
          <b>type</b>
          PObjectAttributes = ^TObjectAttributes;
          TObjectAttributes = <b>record</b>
          Length : ULONG;
          RootDirectory : THandle;
          ObjectName : PUnicodeString;
          Attributes : ULONG;
          SecurityDescriptor : PSecurityDescriptor;
          SecurityQualityOfService: PSecurityQualityOfService;
          <b>end</b>;
          <p>
          <i>////////////////////////////////////////////////////////////////////////////////
          //
          // Object attributes for the event which is triggered on desktop switch
          //
          ////////////////////////////////////////////////////////////////////////////////</i>
          <p>
          <b>const</b>
          DesktopSwitchEventNameString = '\BaseNamedObjects\WinSta0_DesktopSwitch';
          DesktopSwitchEventName: TUnicodeString = (
          Length : Length(DesktopSwitchEventNameString) * SizeOf(WideChar);
          MaximumLength: Length(DesktopSwitchEventNameString) * SizeOf(WideChar) + SizeOf(WideChar);
          Buffer : DesktopSwitchEventNameString;
          );
          <p>
          <b>const</b>
          DesktopSwitchEventAccessMask: ACCESS_MASK = SYNCHRONIZE;
          <p>
          <b>const</b>
          DesktopSwitchEventAttributes: TObjectAttributes = (
          Length : SizeOf(TObjectAttributes);
          RootDirectory : 0;
          ObjectName : @DesktopSwitchEventName;
          Attributes : OBJ_CASE_INSENSITIVE;
          SecurityDescriptor : <b>nil</b>;
          SecurityQualityOfService: <b>nil</b>;
          );
          <p>
          <i>////////////////////////////////////////////////////////////////////////////////
          //
          // Nt/ZwOpenEvent
          //
          ////////////////////////////////////////////////////////////////////////////////</i>
          <p>
          <b>const</b>
          ntdll = 'ntdll.dll';
          <p>
          <b>function</b> NtOpenEvent(<b>out</b> EventHandle: THandle; DesiredAccess: ACCESS_MASK; <b>const</b> ObjectAttributes: TObjectAttributes): NTSTATUS; <b>stdcall</b>;
          <b>external</b> ntdll name 'NtOpenEvent';
          <b>function</b> ZwOpenEvent(<b>out</b> EventHandle: THandle; DesiredAccess: ACCESS_MASK; <b>const</b> ObjectAttributes: TObjectAttributes): NTSTATUS; <b>stdcall</b>;
          <b>external</b> ntdll name 'ZwOpenEvent';
          <p>
          <i>////////////////////////////////////////////////////////////////////////////////
          //
          // Utility function for translating NTSTATUS to Win32 error-code
          //
          ////////////////////////////////////////////////////////////////////////////////</i>
          <p>
          <b>function</b> RtlNtStatusToDosError(Status: NTSTATUS): DWORD; <b>stdcall</b>;
          <b>external</b> ntdll name 'RtlNtStatusToDosError';<p></pre&gt

          Comment


          • #6
            Die Benutzung könnte dann so aussehen...<br> (ich gehe davon aus, das dies in einem extra Thread gemacht wird, der nur die Aufgabe hat, auf einen Desktop-Wechsel zu reagieren und eventuell sogar gleich den aktiven Desktop zu bestimmen)

            <pre><p><b>var</b>
            Status: NTSTATUS;
            EventHandle: THandle;
            <b>begin</b>
            Status := ZwOpenEvent(EventHandle, DesktopSwitchEventAccessMask, DesktopSwitchEventAttributes);
            <b>if</b> (Status >= 0) <b>then</b> <i>// negativ bedeutet fehlgeschlagen...</i>
            <b>try</b>
            ShowMessage('Beginne mit Warten...');
            WaitForSingleObject(EventHandle, INFINITE);
            ShowMessage('Triggered!');
            <b>finally</b>
            CloseHandle(EventHandle);
            <b>end</b>
            <b>else</b>
            ShowMessage('Error: ' + SysErrorMessage(RtlNtStatusToDosError(Status)));
            <b>end</b>;<p></pre>

            (der gesamte Quelltext ist mehr oder weniger aus dem Stegreif entstanden und könnte durchaus Tippfehler enthalten, da ich gerade kein Delphi zur Hand habe)<br>
            Die Funktion des NT-Layers (ZwOpenEvent) wird benötigt, da mit den Win32-API-Funktionen keine benannten Objekte aus dem NT-Namensraum geöffnet werden können (vor allem wegen den "\").
            Der Event hat natürlich einen Sicherheitsdeskriptor, in diesem steht, das er von "Jedem" zum Synchronisieren geöffnet werden darf...

            Gruß Nic

            Comment


            • #7
              An den aktiven Desktop kommst Du per <b>OpenInputDesktop</b> und an dessen Namen per <b>GetUserObjectInformation</b> (mit UOI_NAME).

              Gruß Nic

              Comment


              • #8
                Okay, vielen dank, werds heut abend testen und dann über Funktion und Tippfehler berichten ;

                Comment


                • #9
                  So gut, also ich habs halbwegs verdaut und in einem Thread ans laufen gebracht, vergessen hast Du nur ein Ulong , Tippfehler keine!, echt nicht übel. Das ganze ist anscheinend so undokumentiert, das ich im web (nicht mal per copernic) über "WinSta0_DesktopSwitch" etwas finden konnte, mir fehlt nämlich jetzt noch die Möglichkeit, nach einem Wechsel rauszubekommen, welcher Desktop nun aktiv ist. Ist das genauso umständlich oder geht das ein bissel leichter

                  Comment


                  • #10
                    Die Antwort steht ein Posting weiter oben (der Desktop ist umgeschaltet, wenn der Event ausgelöst wird).

                    Gruß Nico

                    PS: Dazu wirst Du warscheinlich nichts finden, bin mal drüber gestolpert und habe nachgesehen, ob es seit NT 4.0 SP0 geht (ja), aber man brauchts eben fast nie... (ULONG ist ab Delphi 5 in Windows.pas deklariert

                    Comment


                    • #11
                      Na das mit dem Event ist mir schon klar aber ich muss ja jetzt je nachdem, welcher Bildschirm aktiv ist die Tasten umschalten bzw. zurücksetzen, ich muss also nach dem Event herausbekommen, bin ich jetzt z.b. auf dem Anmeldebildschirm (Tasten aus) oder auf dem Userdesktop (Tasten zurücksetzen)?

                      Comment


                      • #12
                        Die Desktops haben stets die gleichen Namen <b>Default</b> (interaktiver), <b>ScrSaver</b>? und (Win)<b>Logon</b>.<br>
                        Die genauen Bezeichnungen stehen irgendwo im MSDN.<br>
                        Die Namen des aktivien Desktops bekommst Du mit o.g. beiden Funktionen.

                        gruß Nic

                        Comment


                        • #13
                          Oh sorry, die Nachricht 6 ist mir durch die Lappen gegangen, peinlich. Werde es gleich heute abend ausprobieren, danke

                          Comment


                          • #14
                            So, gut, funktioniert prima. An alle, die das auch irgendwo nutzen wollen schonmal eine info: Ein Desktopwechsel für den Bildschirmschoner findet nur statt, wenn die Passwortabfrage für den Schoner aktiviert wurde (gar nicht mal wirklich unlogisch...)
                            Vielen dank ;

                            Comment


                            • #15
                              Hallo Karsten,

                              hast Du das Problem mit der Abfrage des Users gelöst bekommen?? Wenn ja, könntest Du mir die Lösung mitteilen??

                              Danke,

                              Ola

                              Comment

                              Working...
                              X