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 ?Shellexecute? aus Windows Dienst (https://www.delphipraxis.net/126931-shellexecute-aus-windows-dienst.html)

xweghau 5. Jan 2009 09:50


?Shellexecute? aus Windows Dienst
 
Hallo!

Ich möchte einen Windows Dienst schreiben, in dem ich überprüfe, ob ein bestimmtes Programm läuft. Wenn das Programm nicht läuft, soll es gestartet werden. Die Überprüfung funktioniert und ich kann das Programm auch mit ShellExecute starten. Leider wird das externe Programm aber als Benutzer "System" ausgeführt mit dem "kleinen" Schönheitsfehler, dass es unsichtbar bleibt, obwohl ich als ShowCmd-Parameter "SW_Show" angegeben habe. Das Programm wird mit dem Benutzer "System" gestartet.

Hat jemand eine Ahnung, was ich da evtl. falsch mache?

Nachfolgend der Delphi 7 Prof. Quellcode:
Delphi-Quellcode:
procedure TsvcArchivprgUeberwachung.Timer1Timer(Sender: TObject);
var hProcess: THandle;
    iRet: Integer;
    sPfad: String;
begin
// Beispiel: sPfad := 'c:\Programme\Archiv\Archiv.EXE';
// Beispiel: sTaskname := 'Archiv.EXE';
// Feststellen, ob die Anwendung läuft
  hProcess := GetProcessHandleFromID(GetProcessID(sTaskname));
  if hProcess = 0 then begin
    iRet := ShellExecute(0, 'open', PChar(sPfad), nil, nil, SW_SHOW);
    if iRet < 33 then begin
{Start eines externen Programmes, das eine Fehlermail erzeugt (das hat aus dem Dienst heraus nicht geklappt, daran muss ich noch mal dran arbeiten, aber so läuft es)}
      iRet := ShellExecute(0, 'open', PChar(ExtractFilePath(ParamStr(0)) + '\MailFromArchive.exe'), PChar('Hinweis:'), PChar(''), SW_HIDE );
{Ich überprüfe nicht, ob mein Versuch eine Mail zu erzeugen erfolgreich war (was habe ich davon, es teilt mir ja keiner mit :-))
Falls notwendig: Verlängerung des Prüfintervalls auf eine Stunde, damit nicht zu viele Mails erzeugt werden.}
      If iInterval < 3600000 then Timer1.Interval := 3600000;
    end;
    end
  else
    Timer1.Interval := iInterval;
end;
Danke schon mal fürs Lesen. Ich hoffe, es fehlen keine Infos.

Gruß
Franz

Angel4585 5. Jan 2009 10:02

Re: ?Shellexecute? aus Windows Dienst
 
wenn man ein Programm mit ShellExecute startet wird es mit den gleichen Benutzerrechten ausgestattet wie das aufrufende Programm besitzt.

Hier solltest du dir mal die Methode "CreateProcessAsUSer" anschauen, gibt auch schon ein paar Themen hier im Forum dazu.

messie 5. Jan 2009 10:06

Re: ?Shellexecute? aus Windows Dienst
 
Ausserdem gibt Du als HWnd 0 an, da bin ich nicht sicher, ob das Dein Anzeigeproblem verusacht.

Grüße, Messie

Luckie 5. Jan 2009 10:16

Re: ?Shellexecute? aus Windows Dienst
 
Alles halb richtig. Das Programm wird wahrscheinlich schon ausgeführt, nur sieht man es nicht, da es auf dem Desktop des Dienstes in dessen Windows Station gestartet wird und die sieht ein Benutzer nun mal nicht.

xweghau 6. Jan 2009 13:57

Re: ?Shellexecute? aus Windows Dienst
 
Hallo zusammen!

An Martin:
Ich denke, da hast Du Recht! Ich habe mir mal was zu dem Thema angesehen, aber dazu unten.

An Messie:
Dass ich hwnd = 0 angebe, ist kein Problem. Ich habe das mit notepad aus einer "normalen" Exe getestet, es funktioniert.

An Luckie:
Der Dienst wird auf dem gleichen Server eingesetzt, auf dem auch der Benutzer aktiv ist, in dessen Namen ich die EXE ausführen will.

Danke Euch dreien für die Tipps.

Wie schon an Martin geschrieben habe ich mir etwas zum Thema "CreateProcessAsUser" angesehen. Folgenden Quälcode verwende ich:
Delphi-Quellcode:
function TsvcArchivprgUeberwachung.StartPrg : Boolean;
var lpUsername: LPCWSTR;
    lpDomain: LPCWSTR;
    lpPassword: LPCWSTR;
    lpApplicationName: LPCWSTR;
    lpCommandLine: LPWSTR;
    lpEnvironment: LPVOID;
    sui: STARTUPINFOW;
    pi: PROCESS_INFORMATION;
    iRet: Integer;
begin
    Result := True;
    lpUsername := 'xweghau';
    lpPassword := 'triplex';//Keine Sorge, es ist nicht das echte Passwort
    lpApplicationName := 'notepad.exe';//'c:\programme\archiv\archiv.exe';
    lpCommandLine := nil;
    lpEnvironment := nil;
    lpDomain := nil;
    ZeroMemory(@sui, sizeof(sui));
    // Fill size member
    sui.cb := sizeof(sui);
    // Create process
    if (CreateProcessWithLogonW(
     lpUsername,
     lpDomain, // Domain
     lpPassword,
     LOGON_WITH_PROFILE, // No special options
     lpApplicationName, // Module to execute
     lpCommandLine, // Activates extensions
     CREATE_NEW_CONSOLE, // Only these options for now
     lpEnvironment,
     nil, // Use current directory
     sui, // STARTUPINFO
     pi // PROCESS_INFORMATION
     )) = False then begin
//Mailbenachrichtigung erzeugen (derzeit mit externem Programm)
      iRet := ShellExecute(0, 'open', PChar(ExtractFilePath(ParamStr(0)) + '\MailFromArchive.exe'), PChar('Das Programm konnte
              nicht gestartet werden.'), nil, SW_HIDE );
//Wenn die Mail nicht erzeugt wird ... Pech, was soll ich auch machen ...
      Result := False;
    end;
end;
Verwende ich meinen Code in einer normalen EXE, dann wird notepad aufgerufen, allerdings läuft die EXE Datei ja auch im gleichen Benutzerkontext.

Ich habe den Code zusammengestrichen, alles was nicht zum Thema gehört, habe ich entfernt (hoffentlich nicht zuviel). GetLastError() liefert mir den Wert 5 zurück. Leider weiß ich nicht, wo ich die Bedeutung erklärt finde. Könnt Ihr mir da helfen?

Gruß
Franz

Luckie 6. Jan 2009 14:02

Re: ?Shellexecute? aus Windows Dienst
 
Zitat:

Zitat von xweghau
An Luckie:
Der Dienst wird auf dem gleichen Server eingesetzt, auf dem auch der Benutzer aktiv ist, in dessen Namen ich die EXE ausführen will.

Du solltest dich mal mit dem Sicherheitskonzept von Windows auseinandersetzen. Mit WindowsStation ist kein separater Rechner gemeint. WindowsStations gehöen zu dem Sicherheitskonzept von Windows. Dies in einem Beitrag zu eräutern würde zu weit führen.

Zitat:

Ich habe den Code zusammengestrichen, alles was nicht zum Thema gehört, habe ich entfernt (hoffentlich nicht zuviel). GetLastError() liefert mir den Wert 5 zurück. Leider weiß ich nicht, wo ich die Bedeutung erklärt finde. Könnt Ihr mir da helfen?
Entweder du schlägst den Fehlercode im Windows SDK nach oder du lässt ihn dir mit Delphi-Referenz durchsuchenSysErrorMessage im Klartext ausgeben.

xweghau 6. Jan 2009 14:16

Re: ?Shellexecute? aus Windows Dienst
 
Hallo Michael,

in der Antwort an Dich habe ich mich missverständlich ausgedrückt. Was ich meinte: Der Dienst soll das Programm im Kontext eines bestimmten angemeldeten Benutzers (wie ich das herausbekomme, habe ich schon im Forum gefunden) starten. Dieser sollte das Programm dann sofort zu sehen bekommen, aber das klappte mit ShellExecute nicht, das habe ich jetzt verstanden. (Ich hoffe, ich habe mich jetzt besser ausgedrückt. :oops: )

Danke für den Tipp.

Gruß
Franz


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