Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Service Application - CreateProcess... (https://www.delphipraxis.net/164026-service-application-createprocess.html)

pate444 26. Okt 2011 09:52

Service Application - CreateProcess...
 
Hallo zusammen,

ich habe leider ein Problem mit meinem Dienst, den ich in Delphi geschrieben habe.

Kurze Beschreibung des Dienstes:

Der Dienst soll später einen Pfad zu einem XML-File einlesen und vom XML-File die Werte einlesen. Gestartet werden können dann mehrere Anwendungen, die einem bestimmten Prozessorkern zugewiesen werden.

Problem:

In dem Dienst arbeite ich mit der Funktion CreateProcess (bzw. CreateProcessWithLogonW). Lasse ich das Programm nicht als Dienst ausführen, sondern als eine normale Konsolenanwendung, funktioniert es wunderbar. Die einzelnen Anwendungen starten und werden direkt einem Prozessorkern zugewiesen.
Jedoch treten die ersten Probleme auf, sobald ich es als Dienst laufen lasse.

Ich habe schon mehrere Ansätze verfolgt. Zunächst lief der Dienst unter 'Lokales System', mit der Folge, dass ein Prozess im Task Manager unter einer ProzessID vermerkt wurde, jedoch schien dieser "tot" zu sein, da er nichts gemacht hat.

Danach habe ich die Option "Datenaustausch zwischen Dienst und Desktop zulassen" aktiviert. Nachdem ich den Dienst mit den Informationen "gefüttert" habe, startet auch ein Fenster, jedoch ohne Inhalt und ohne eine Möglichkeit etwas mit der Anwendung anzufangen. Auf den Prozess im Task Manager kann ebenfalls nicht zugegriffen werden.

Als letztes habe ich versucht den Dienst über ein anderes Benutzerkonto mit Admin-Rechten zu starten, leider auch wieder ohne Erfolg.

Ich bin leider mit meinem Latein am Ende und belästige Euch nur ungern, aber ich hoffe jemand kann mir eventuell bei diesem Problem helfen.

Danke!

Gruß

Luckie 26. Okt 2011 10:29

AW: Service Application - CreateProcess...
 
Zitat:

Zitat von pate444 (Beitrag 1132593)
Der Dienst soll ... Gestartet werden können dann mehrere Anwendungen

Ich habe es mal auf das wesentliche zusammengeschrumpft.

[qzuote]als eine normale Konsolenanwendung, funktioniert es wunderbar. Die einzelnen Anwendungen starten und werden direkt einem Prozessorkern zugewiesen.[/quote]
Du solltest dich mit der Funktionsweise und internen Aufbau von Windows vertraut machen. Du scheinst da ziemlich ins Blaue zu programmieren. Ein Dienst läuft in einer anderen WindowsStation als die Benutzer Prozesse. Innerhalb dieser WindowsStation existiert wieder ein Desktop in dem dann die vom Dienst gestarteten Programme laufen. Der interaktive Anwender sieht die gestarteten Programm als nicht und kann somit auch nicht mit ihen interagieren.

Zitat:

Ich habe schon mehrere Ansätze verfolgt. Zunächst lief der Dienst unter 'Lokales System', mit der Folge, dass ein Prozess im Task Manager unter einer ProzessID vermerkt wurde, jedoch schien dieser "tot" zu sein, da er nichts gemacht hat.
Was heißt "tot"?`Wenn er keine CPU-Zeit verbraucht hat, heißt das nur, dass der nichts zu tun hatte.

Zitat:

Danach habe ich die Option "Datenaustausch zwischen Dienst und Desktop zulassen" aktiviert.
Aua. Läuft das unter dem Motto: "Wir haben noch nicht genug Sicherheitslücken, lasst uns selbst noch welche aufreißen"? Diese Option gibt es ab Vista nicht mehr. wäre also auch keine Lösung, wenn es funktioniert hätte.

Zitat:

Auf den Prozess im Task Manager kann ebenfalls nicht zugegriffen werden.
Logisch. Da der Prozess vom Dienst gestartet wurde, läuft er auch in dessen Benutzerkontext und erbt dessen Berechtigungen usw. Und unter Windows kann man eben nicht so einfach die Prozesse eines anderen Benutzers beenden.

Zitat:

Als letztes habe ich versucht den Dienst über ein anderes Benutzerkonto mit Admin-Rechten zu starten, leider auch wieder ohne Erfolg.
Siehe ganz oben.

Was du eigentlich willst, ist doch dass dein Dienst ein Programm startet mit dem der angemeldete interaktive Benutzer interagieren kann oder? Eventuell hilft dir dabei das: http://www.c-plusplus.de/forum/263737

pate444 26. Okt 2011 10:39

AW: Service Application - CreateProcess...
 
Zitat:

Was du eigentlich willst, ist doch dass dein Dienst ein Programm startet mit dem der angemeldete interaktive Benutzer interagieren kann oder?
Ja genau.:-D Der soll später durch einen angemeldeten Benutzer auf einem Server mehrere Rechnungen starten.

Ich werde mir erstmal deinen Link anschauen. Danke.

Bummi 26. Okt 2011 12:00

AW: Service Application - CreateProcess...
 
Du kannst mit Deinem Dienst u.a. über Named Pipes oder per TCP-IP kommunizieren ......

Luckie 26. Okt 2011 12:37

AW: Service Application - CreateProcess...
 
Zitat:

Zitat von Bummi (Beitrag 1132614)
Du kannst mit Deinem Dienst u.a. über Named Pipes oder per TCP-IP kommunizieren ......

Hm, davon hat er nichts geschrieben. Er will doch nur aus dem Dienst heraus eine Anwendung für den angemeldeten interaktiven Benutzer starten.

Bummi 26. Okt 2011 12:40

AW: Service Application - CreateProcess...
 
@Luckie

Dann habe ich ihn wohl missverstanden, ich dachte er wolle eine Art Middle Tier basteln

pate444 9. Nov 2011 07:54

AW: Service Application - CreateProcess...
 
Hallo zusammen,

ich habe mich die Tage mit dem Lösungsansatz befasst und dieser Quellcode ist dabei herausgekommen.
Jedoch habe ich ein kleines Problem mit einigen Zeilen (rot makiert). Meine Recherchen im Netz haben bisher noch keine positiven Ergebnisse gezeigt.

Code:
interface

uses
  Windows;

function CreateProcessAsUserA(Index: String; Counter: Integer
          ): Cardinal;

function ProcessIdToSessionId (ProcessId : DWORD; var SessionId : DWORD) : BOOL;
         stdcall; external kernel32 name 'ProcessIdToSessionId';


implementation

function CreateProcessAsUserA(Index: String; Counter: Integer
          ): Cardinal;
var
   sui : TStartUpInfo;
   Pi : TProcessInformation;
   hNewToken: THandle;
   hProcessToken: THandle;
   dwSessionId: dword;
   Prozess: Boolean;
   processID: dword;
   reLength: dword;
var
   WTSGetActiveConsoleSessionId: function: DWord; stdcall;
begin
    processID:= GetCurrentProcessID;
    if ProcessIdToSessionId(processID,dwSessionID) then

    if dwSessionID <> $FFFFFFFF then
    begin
      hProcessToken := 0;

    OpenProcessToken(GetCurrentProcess(),
    TOKEN_ADJUST_PRIVILEGES or
    TOKEN_QUERY,
    hProcessToken);

    DuplicateTokenEx(hProcessToken,
    MAXIMUM_ALLOWED,
    Nil,
    SecurityImpersonation,
    TokenPrimary,
    hNewToken);

    GetTokeninformation(hNewToken,
    TokenSessionID,
    @dwSessionID,
    sizeof(@dwSessionid),
    reLength);

    SetTokenInformation(hNewToken,
    TokenSessionId,
    @dwSessionId,
    sizeof(dwSessionID));

    //CreateProcessAsUser
    Prozess:= CreateProcessAsUser(hNewToken,
              nil,
              PwideChar(index),
              nil,
              nil,
              false,
              Create_New_Console or NORMAL_PRIORITY_CLASS,
              nil,
              nil,
              sui,
              pi);

    //Allocate process to CPU
    SetProcessAffinityMask(pi.hProcess, Counter+1);

    Result:= pi.dwProcessId;

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
end;

end;



end.
Die Funktion bricht bei SetTokenInformation ab. Daher vermute ich, dass es was mit der dwSessionID zusammenhängt.

Edit: Die Funktion läuft jetzt durch, jedoch ohne einen Prozess zu starten. dwSessionID wird immer der Wert 0 zugewiesen...
Kleine Verbesserung vorgenommen, jetzt bekommt dwSessionID seinen Wert, nur leider immer noch kein gestarter Prozess... :/

pate444 16. Nov 2011 08:16

AW: Service Application - CreateProcess...
 
Problem gelöst. Alles funktioniert jetzt. Ich bedanke mich für die Hilfe Lucky.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:07 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