AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Dienst: Aktuellen Inputdesktop auslesen
Thema durchsuchen
Ansicht
Themen-Optionen

Dienst: Aktuellen Inputdesktop auslesen

Ein Thema von Harry Stahl · begonnen am 8. Jul 2015 · letzter Beitrag vom 12. Jul 2015
Antwort Antwort
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.055 Beiträge
 
Delphi 12 Athens
 
#1

AW: Dienst: Aktuellen Inputdesktop auslesen

  Alt 8. Jul 2015, 05:41
Das geht per Definition nicht mehr. Aus Sicherheitsgründen.

Ein Programm im Benutzerkontext, das die Daten anzeigt, ist genau das richtige. Wir benutzen dafür eine Webseite. Im Dienst ist dafür ein Datasnap Server integriert.

Das hat auch den Vorteil, dass sich der Dienst voll auf die Daten konzentrieren kann und keine GUI-Logik mehr benötigt.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#2

AW: Dienst: Aktuellen Inputdesktop auslesen

  Alt 8. Jul 2015, 16:42
Ja, das hatte ich befürchtet.

Gerade mal getestet, wenn das Serverprogramm als Dienst läuft, dann kann ich zwar mit dem Dienst Dateien auf dem Rechner kopieren, löschen, umbenennen etc. aber nicht ausführen?

ShellExecute scheint dann nicht zu funktionieren?

Wie starte ich dann mit dem Dienst ein GUI-Programm im gerade aktuellen User-Kontext? Auf einen Input-Desktop kann ich ja mit dem Dienst nicht wechseln.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Dienst: Aktuellen Inputdesktop auslesen

  Alt 8. Jul 2015, 16:47
Ha, genau damit habe ich mich letztens auch rumgeschlagen. Es geht. Man muss auch nicht bei jedem Wechsel eine neue Instanz starten, obwohl es viele Programme gibt, die es genau so machen.

Es ist aber auch tatsächlich immer noch möglich (zumindest unter Windows 7), GUI-Prozesse mit System-Rechten laufen zu lassen. Auch wenn Microsoft das extrem verschleiert (aus gutem Grund).

Man braucht nur (*) einen Dienst, der das Programm einmal am Anfang mit System-Rechten startet. Wenn das Programm mit System-Rechten erst mal läuft, dann klappt auch das Wechseln des Desktops wieder.

Hier mal meine Funktion zum Starten eines Prozesses mit System-Rechten (das Ergebnis von mehreren Tagen Recherche):
Delphi-Quellcode:
function CreateElevatedUserProcess(ProcessPath: String; ProcessArgs: String; out Log: String): Boolean;
var
  OwnToken: HANDLE;
  NewToken: HANDLE;
  SecurityAttributes: SECURITY_ATTRIBUTES;
  SessId: DWORD;
  UiAccess: DWORD;
  CommandLine: String;
  StartupInfo: TSTARTUPINFO;
  ProcessInformation: PROCESS_INFORMATION;
begin
  Log := 'OpenProcessToken';
  Result := OpenProcessToken(GetCurrentProcess,
    TOKEN_ALL_ACCESS or TOKEN_ADJUST_SESSIONID,
    @OwnToken);
  if not Result then exit;

  SecurityAttributes.nLength := sizeof(SecurityAttributes);
  SecurityAttributes.bInheritHandle := TRUE;
  SecurityAttributes.lpSecurityDescriptor := nil;

  Log := 'DuplicateTokenEx';
  Result := DuplicateTokenEx(
    OwnToken,
    MAXIMUM_ALLOWED,
    @SecurityAttributes,
    SecurityImpersonation,
    TokenPrimary,
    @NewToken);
  if not Result then exit;

  Log := 'WTSGetActiveConsoleSessionId';
  SessID := WTSGetActiveConsoleSessionId;

  Log := 'SetTokenInformation (TokenSessionId)';
  Result := SetTokenInformation(NewToken, TokenSessionId, @SessId, sizeof(SessId));
  if not Result then exit;

  UiAccess := 1;
  Log := 'SetTokenInformation (UiAccess)';
  Result := SetTokenInformation(NewToken, TokenUIAccess, @UiAccess, sizeof(UiAccess));
  if not Result then exit;

  FillChar(StartupInfo, sizeof(StartupInfo), 0);
  StartupInfo.wShowWindow := SW_SHOWDEFAULT;
  StartupInfo.lpDesktop := 'winsta0\Default';

  CommandLine := '"' + ProcessPath + '"' + ' ' + ProcessArgs;
  Log := 'CreateProcessAsUser';
  Result := CreateProcessAsUser(
    NewToken,
    LPCTSTR(ProcessPath),
    LPTSTR(CommandLine),
    @SecurityAttributes,
    @SecurityAttributes,
    FALSE,
    0,
    nil,
    nil,
    @StartupInfo,
    @ProcessInformation);

end;
Aber bitte mit Vorsicht genießen!

Du könntest dich bei mir revanchieren, indem du mal testest, ob das ganze unter Windows 8 und Windows 10 auch noch funktioniert . Habe es bisher nur unter Windows 7 getestet.

Edit:
(*) Achja, es gibt noch ein paar Dinge zu beachten. Programm und Dienst (?) müssen digital signiert sein und in einem „sicheren“ Ordner liegen. Andernfalls wird der Start verweigert. Ein „sicherer“ Ordner ist z.B. „C:\Programme“. Sind noch mal zusätzliche Hürden von Microsoft.

Geändert von Namenloser ( 8. Jul 2015 um 17:18 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#4

AW: Dienst: Aktuellen Inputdesktop auslesen

  Alt 8. Jul 2015, 18:42
Hey, da hab ich ja echt Glück gehabt!

Klappt auch, insofern schon mal vielen Dank!

Und hier die erste Rückmeldung: Funktioniert auch unter Windows 8.1. Dabei war der Dienst noch nicht mal signiert und lag auch nicht in einem geschützten Bereich (in der installierten Version wird beides aber der Fall sein, insofern ist es egal, ob diese Anforderungen nun letztlich gegeben sein müssen oder nicht).

Zu Windows 10 gebe ich später noch eine Rückmeldung.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#5

AW: Dienst: Aktuellen Inputdesktop auslesen

  Alt 8. Jul 2015, 19:03
Vielleicht noch eine Nachfrage:

Wie bekommt mein Service jetzt eigentlich mit, dass gerade kein Anmelde- oder Gespert-Desktop angezeigt wird, bzw. dass jetzt ein User-Desktop aktiv ist.

Alle Anfragen zur Windows-Station liefern zu jeder Zeit leider nur "Service-0x0-3e7$" zurück.

Ein "InputDesktop" steht ja nicht zur Verfügung, anhand dessen ich einen Wechsel des Desktops testen könnte.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Dienst: Aktuellen Inputdesktop auslesen

  Alt 8. Jul 2015, 19:18
Das müsstest du aus dem vom Dienst gestarteten Prozess heraus machen. Der Dienst selbst hat keinen Zugriff darauf.

Kann sein, dass das mit der Signatur und dem sicheren Ort doch nur für den gestarteten Prozess gilt und nicht für den Dienst. Deswegen hatte ich auch hinter Dienst ein Fragezeichen gesetzt. Aber wenn man schon den Prozess signiert, kann man den Dienst ja gleich auch signieren.

Geändert von Namenloser ( 8. Jul 2015 um 19:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#7

AW: Dienst: Aktuellen Inputdesktop auslesen

  Alt 8. Jul 2015, 19:36
Ah ja, habe gerade gesehen, mein Dienst kann das Programm schon starten, auch wenn noch gar keiner am PC angemeldet ist. Nehme an, das geht dann automatisch in den ersten User-Desktop rein.

Und von da aus kann das GUI-Programm dann arbeiten wie sonst auch.

Wobei dann insgesamt nicht mehr so ein riesengroßer Unterschied zum Autostart ist, zumindest wenn sonst eh nur ein User am PC arbeitet.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.055 Beiträge
 
Delphi 12 Athens
 
#8

AW: Dienst: Aktuellen Inputdesktop auslesen

  Alt 9. Jul 2015, 06:45
Wobei die saubere Lösung dennoch ein komplett eigenständiges Programm wäre, das im Autostart liegen oder vom Benutzer gestartet werden kann.

Ein weiterer Vorteil der Lösung ist, dass man nicht befürchten muss, dass diese in zukünftigen Windowsversionen plötzlich nicht mehr funktioniert...

Und ich persönlich würde eine Lösung, die das anders macht, auch nicht einsetzen. In einer Lösung, die in Firmen zum Einsatz kommt, wäre das z.B. in der Regel ein NoGo.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort


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 11:34 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