AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Windows 10 Logon / Logoff erkennen

Ein Thema von Corsair_ML · begonnen am 20. Jan 2021 · letzter Beitrag vom 21. Jan 2021
Antwort Antwort
Seite 1 von 2  1 2   
Corsair_ML

Registriert seit: 30. Aug 2006
Ort: Thüringen
5 Beiträge
 
Delphi 6 Professional
 
#1

Windows 10 Logon / Logoff erkennen

  Alt 20. Jan 2021, 19:45
Hallo,

ich lese schon lange im Forum mit und konnte so viele Probleme lösen. Diesmal komme ich aber nicht weiter. Ich programmiere als Hobby mit Delphi 6 Professional unter Windows XP in VirtualBox.

Ich bin dabei mir eine Stechuhr für das Home Office zu erstellen. Dabei möchte ich, dass beim Sperren von Windows 10 die Zeit bis zum Entsperren gestoppt wird. Diese Zeit nutze ich als Pause. Ich habe aber beim Erkennen, dass Windows gesperrt bzw. entsperrt Probleme. Durch Recherche bin ich auf folgende Lösung gekommen (siehe auch hier https://www.swissdelphicenter.ch/en/...de.php?id=1109 ):

Code:
unit Wtsapi;
 
interface
 
 
uses
  Windows;
 
const
  // The WM_WTSSESSION_CHANGE message notifies applications of changes in session state.
  WM_WTSSESSION_CHANGE = $2B1;
 
  // wParam values:
  WTS_CONSOLE_CONNECT = 1;
  WTS_CONSOLE_DISCONNECT = 2;
  WTS_REMOTE_CONNECT = 3;
  WTS_REMOTE_DISCONNECT = 4;
  WTS_SESSION_LOGON = 5;
  WTS_SESSION_LOGOFF = 6;
  WTS_SESSION_LOCK = 7;
  WTS_SESSION_UNLOCK = 8;
  WTS_SESSION_REMOTE_CONTROL = 9;
 
  // Only session notifications involving the session attached to by the window
  // identified by the hWnd parameter value are to be received.
  NOTIFY_FOR_THIS_SESSION = 0;
  // All session notifications are to be received.
  NOTIFY_FOR_ALL_SESSIONS = 1;
 
 
function RegisterSessionNotification(Wnd: HWND; dwFlags: DWORD): Boolean;
function UnRegisterSessionNotification(Wnd: HWND): Boolean;
function GetCurrentSessionID: Integer;
 
implementation
 
function RegisterSessionNotification(Wnd: HWND; dwFlags: DWORD): Boolean;
  // The RegisterSessionNotification function registers the specified window
  // to receive session change notifications.
  // Parameters:
  // hWnd: Handle of the window to receive session change notifications.
  // dwFlags: Specifies which session notifications are to be received:
  // (NOTIFY_FOR_THIS_SESSION, NOTIFY_FOR_ALL_SESSIONS)
type
  TWTSRegisterSessionNotification = function(Wnd: HWND; dwFlags: DWORD): BOOL; stdcall;
var
  hWTSapi32dll: THandle;
  WTSRegisterSessionNotification: TWTSRegisterSessionNotification;
begin
  Result := False;
  hWTSAPI32DLL := LoadLibrary('Wtsapi32.dll');
  if (hWTSAPI32DLL > 0) then
  begin
    try @WTSRegisterSessionNotification :=
        GetProcAddress(hWTSAPI32DLL, 'WTSRegisterSessionNotification');
      if Assigned(WTSRegisterSessionNotification) then
      begin
        Result:= WTSRegisterSessionNotification(Wnd, dwFlags);
      end;
    finally
      if hWTSAPI32DLL > 0 then
        FreeLibrary(hWTSAPI32DLL);
    end;
  end;
end;
 
function UnRegisterSessionNotification(Wnd: HWND): Boolean;
  // The RegisterSessionNotification function unregisters the specified window
  // Parameters:
  // hWnd: Handle to the window
type
  TWTSUnRegisterSessionNotification = function(Wnd: HWND): BOOL; stdcall;
var
  hWTSapi32dll: THandle;
  WTSUnRegisterSessionNotification: TWTSUnRegisterSessionNotification;
begin
  Result := False;
  hWTSAPI32DLL := LoadLibrary('Wtsapi32.dll');
  if (hWTSAPI32DLL > 0) then
  begin
    try @WTSUnRegisterSessionNotification :=
        GetProcAddress(hWTSAPI32DLL, 'WTSUnRegisterSessionNotification');
      if Assigned(WTSUnRegisterSessionNotification) then
      begin
        Result:= WTSUnRegisterSessionNotification(Wnd);
      end;
    finally
      if hWTSAPI32DLL > 0 then
        FreeLibrary(hWTSAPI32DLL);
    end;
  end;
end;
 
function GetCurrentSessionID: Integer;
 // Getting the session id from the current process
type
  TProcessIdToSessionId = function(dwProcessId: DWORD; pSessionId: DWORD): BOOL; stdcall;
var
  ProcessIdToSessionId: TProcessIdToSessionId;
  hWTSapi32dll: THandle;
  Lib : THandle;
  pSessionId : DWord;
begin
  Result := 0;
  Lib := GetModuleHandle('kernel32');
  if Lib <> 0 then
  begin
    ProcessIdToSessionId := GetProcAddress(Lib, '1ProcessIdToSessionId');
    if Assigned(ProcessIdToSessionId) then
    begin
      ProcessIdToSessionId(GetCurrentProcessId(), DWORD(@pSessionId));
      Result:= pSessionId;
    end;
  end;
end;
 
end.
Und die Nutzung im Programm

Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Wtsapi;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    FRegisteredSessionNotification : Boolean;
    procedure AppMessage(var Msg: TMSG; var HAndled: Boolean);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AppMessage(var Msg: TMSG; var Handled: Boolean);
var
  strReason: string;
begin
  Handled := False;
  Memo1.Lines.Add('AppMessage');
  // Check for WM_WTSSESSION_CHANGE message
  if Msg.Message = WM_WTSSESSION_CHANGE then
  begin
    Memo1.Lines.Add('Message '+IntToStr(Msg.wParam));
     case Msg.wParam of
       WTS_CONSOLE_CONNECT:
           strReason := 'WTS_CONSOLE_CONNECT';
       WTS_CONSOLE_DISCONNECT:
           strReason := 'WTS_CONSOLE_DISCONNECT';
       WTS_REMOTE_CONNECT:
           strReason := 'WTS_REMOTE_CONNECT';
       WTS_REMOTE_DISCONNECT:
           strReason := 'WTS_REMOTE_DISCONNECT';
       WTS_SESSION_LOGON:
           strReason := 'WTS_SESSION_LOGON';
       WTS_SESSION_LOGOFF:
           strReason := 'WTS_SESSION_LOGOFF';
       WTS_SESSION_LOCK:
           strReason := 'WTS_SESSION_LOCK';
       WTS_SESSION_UNLOCK:
           strReason := 'WTS_SESSION_UNLOCK';
       WTS_SESSION_REMOTE_CONTROL:
           begin
             strReason := 'WTS_SESSION_REMOTE_CONTROL';
             // GetSystemMetrics(SM_REMOTECONTROL);
           end;
      else
        strReason := 'WTS_Unknown';
     end;
   // Write strReason to a Memo
   //ShowMessage(strReason + ' ' + IntToStr(msg.Lparam));
   Memo1.Lines.Add(strReason + ' ' + IntToStr(msg.Lparam));
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 // retrieve current session ID
 //ShowMessage(Inttostr(GetCurrentSessionID));
 Memo1.Lines.Add('CurrentSessionID '+ Inttostr(GetCurrentSessionID))
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // register the window to receive session change notifications.
  FRegisteredSessionNotification := RegisterSessionNotification(Handle, NOTIFY_FOR_THIS_SESSION);
  Application.OnMessage := AppMessage;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // unregister session change notifications.
  if FRegisteredSessionNotification then
    UnRegisterSessionNotification(Handle);
end;

end.
Leider kann ich aber keine Änderung der
Code:
Msg.Message = WM_WTSSESSION_CHANGE
feststellen. Es passiert weder unter Windows XP noch unter Windows 10 etwas.
Fehlermeldungen gibt es auch nicht...

Kann mir bitte jemand einen Tipp geben?

Danke und viele Grüße!

Markus
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Windows 10 Logon / Logoff erkennen

  Alt 20. Jan 2021, 20:55
Hm, das du nach dem Aufrufen und damit dynamischen Laden von WTSRegisterSessionNotification und WTSUnRegisterSessionNotification die DLL gleich wieder entlädst scheint mir nicht ganz so richtig zu sein.
Ändere das mal.

Davon abgesehen sagt die MSDN:
Zitat:
Minimum supported client Windows Vista
Daher fällt jeder Versuch unter Windows XP ins Wasser.

Für Windows 10 probiere mal spaßeshalber NOTIFY_FOR_ALL_SESSIONS und die Variante mit procedure WMWTSSESSIONCHANGE(var AMsg: TMessage); message WM_WTSSESSION_CHANGE; anstatt über Application.OnMessage zu gehen (siehe: https://www.delphipraxis.net/97244-s...-erkennen.html).
  Mit Zitat antworten Zitat
Corsair_ML

Registriert seit: 30. Aug 2006
Ort: Thüringen
5 Beiträge
 
Delphi 6 Professional
 
#3

AW: Windows 10 Logon / Logoff erkennen

  Alt 20. Jan 2021, 21:33
Hallo TiGü,

ich testete immer unter Windows 10:

Unregister kommt doch erst beim FormDestroy - oder habe ich was übersehen?
Code:
NOTIFY_FOR_ALL_SESSIONS
habe ich eingestellt - ohne Veränderung
Code:
procedure WMWTSSESSIONCHANGE(var AMsg: TMessage); message WM_WTSSESSION_CHANGE;
habe ich auch probiert, ebenfalls ohne Erfolg.
Kann es sein, dass es wie in dem verlinkten Post ist: das geht nur von Windows XP bis Vista?

Viele Grüße

Markus
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Windows 10 Logon / Logoff erkennen

  Alt 20. Jan 2021, 22:56
Zitat von Ich:
...die DLL gleich wieder entlädst...
Unregister kommt doch erst beim FormDestroy - oder habe ich was übersehen?
Kommentiere bitte mal alle FreeLibrary Aufrufe aus.
  Mit Zitat antworten Zitat
Benutzerbild von Moombas
Moombas

Registriert seit: 22. Mär 2017
Ort: bei Flensburg
525 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Windows 10 Logon / Logoff erkennen

  Alt 21. Jan 2021, 08:23
Ich kenne nun eure interne IT-Struktur (dürfen die Benutzer die Aufgabenplanung bearbeiten?) nicht, aber anstatt das über das eigene Programm laufen zu lassen, könntest du das über die Aufgabenplanung lösen:

Aufgabenplanung -> Windows -> 2 neue Aufgaben erstellen (jedesmal wenn dein Programm gestartet wird, prüfen ob die Aufgaben existieren, sonst neu anlegen)
1. Aufgabe: Trigger: Bei Arbeitsstationssperre (Pausen beginn) -> Sub-Programm ausführen das entweder einen entsprechenden Eintrag in eine Datenbank oder an deine Stechuhr übergibt.
2. Aufgabe: Trigger: Beim Aufheben der Arbeitsstationssperre (Pausen Ende) -> Sub-Programm ausführen das entweder einen entsprechenden Eintrag in eine Datenbank oder an deine Stechuhr übergibt.

OT: Ob ein gesperrter PC nun wirklich immer eine Pause zur Folge hat möchte ich dennoch in Frage stellen! Beim Gang zum WC oder Teilnahme an Meetings/Brainstorming odder ähnlichem wird der PC höchstwahrscheinlich gesperrt sein obwohl es keine Pause ist.
Und wer seinen PC in der Pause nicht sperrt, umgeht diesen Mechanismus... und komm mir nicht mit Autosperren nach X-Minuten, denn schon das verfälscht das Ergebnis und kann umgangen werden...
Der Weg ist das Ziel aber man sollte auf dem Weg niemals das Ziel aus den Augen verlieren.

Geändert von Moombas (21. Jan 2021 um 08:28 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Windows 10 Logon / Logoff erkennen

  Alt 21. Jan 2021, 08:44
Moombas, es geht ihm um eine Stechuhr für Zuhause in der Heimarbeit (Home Office).
  Mit Zitat antworten Zitat
Benutzerbild von holger_barntrup
holger_barntrup

Registriert seit: 1. Feb 2007
Ort: Barntrup
97 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Windows 10 Logon / Logoff erkennen

  Alt 21. Jan 2021, 08:46
Ich hatte über so was auch schon mal nachgedacht aber nie angegangen.
Mein Denkansatz war das aus dem Eventlog auszulesen.

Das hatte ich mir seinerzeit dazu gespeichert: https://theroadtodelphi.com/2011/10/...93-event-logs/

Die Ereignisse die dich interessieren sind die 4800 sperren u 4801 entsperren.

Vielleicht hilft es dir.
Gruß Holger
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
673 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Windows 10 Logon / Logoff erkennen

  Alt 21. Jan 2021, 08:54
Da sProblem ist, soweit ich weiss, das service object von Delphi. Es gibt Dir die Information einfach nicht, wenn diese Events eintreten. Ich habe für dieses Projekt einfach auf DDService gewechselt, das ist OpenSource und hat ein Event dafür "procedure TDDServiceSessionChange(Sender: TDDService; EventType, SessionID: Integer)"

EventType ist dabei deine WTS_XXXX mit Logon etc.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Windows 10 Logon / Logoff erkennen

  Alt 21. Jan 2021, 09:09
Wenn du jetzt eine funktionierende Lösung brauchst, dann kannst du dir auch das kostenlose WinLogOnView von NirSoft ansehen.
https://www.nirsoft.net/utils/window...imes_view.html

Das verwendet den Ansatz mit dem Eventlog/Ereignisanzeige.
  Mit Zitat antworten Zitat
Corsair_ML

Registriert seit: 30. Aug 2006
Ort: Thüringen
5 Beiträge
 
Delphi 6 Professional
 
#10

AW: Windows 10 Logon / Logoff erkennen

  Alt 21. Jan 2021, 18:20
Hallo,

@TiGü
Ich habe die FreeLibrary Aufrufe auskommentiert, hat aber nichts geändert.
Mit dem Tool von NirSoft könnte man das händisch machen. Stimmt. Überlege ich mir, wenn ich wirklich keinen anderen Weg finde.

@holger_barntrup
Der von dir verlinkte Ansatz sieht interessant aus. Den werde ich mir anschauen.

@MyRealName
DDService habe ich nicht beim Suchen gefunden. Hast du dazu bitte einen Link?


Vielen Dank!

Markus
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz