Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   FreePascal CMD / Prozess prüfen (https://www.delphipraxis.net/203860-cmd-prozess-pruefen.html)

Moombas 1. Apr 2020 12:36

CMD / Prozess prüfen
 
Moin zusammen,

auch wenn es irgendwie ein blödes Problem ist, brauche ich eure unterstützung.

Ich habe folgende Konsolenanwendung in Lazarus:
Delphi-Quellcode:
program Backup;
{$mode Delphi}{$H+}
uses
  ShellAPI;

{$R *.res}

begin
  ShellExecute(0, nil, PChar('cmd'), PChar('/c wbadmin.exe start backup -quiet -vssCopy -backupTarget:D: -include:C:'), nil, 1);
end.
Mein Problem:
Ich muss wissen wann die cmd geschlossen wird um erst dann dieses Programm auch erst zu beenden.
Hab schon viel gesucht, die Lösung scheint ja CreateProcess zu sein, jedoch bin ich scheinbar zu blöd diesen wirklich zu verstehen und somit anzuwenden/adaptieren.

Jumpy 1. Apr 2020 12:52

AW: CMD / Prozess prüfen
 
Keine Ahnung, wo ich das seinerzeit gefunden habe, vllt. hier in der DP?

Delphi-Quellcode:
function TMain.ShellExecute_AndWait(FileName: string; Params: string): bool;
var
  exInfo: TShellExecuteInfo;
  Ph: DWORD;
begin
  FillChar(exInfo, SizeOf(exInfo), 0);
  with exInfo do
  begin
    cbSize := SizeOf(exInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
    Wnd := GetActiveWindow();
    exInfo.lpVerb := 'open';
    exInfo.lpParameters := PChar(Params);
    lpFile := PChar(FileName);
    nShow := SW_SHOWNORMAL;
  end;
  if ShellExecuteEx(@exInfo) then
    Ph := exInfo.hProcess
  else
  begin
    ShowMessage(SysErrorMessage(GetLastError));
    Result := true;
    exit;
  end;
  while WaitForSingleObject(exInfo.hProcess, 50) <> WAIT_OBJECT_0 do
    Application.ProcessMessages;
  CloseHandle(Ph);

  Result := true;
end;

Delphi.Narium 1. Apr 2020 13:01

AW: CMD / Prozess prüfen
 
Habe in meinem "Gewusel" dashier gefunden:
Delphi-Quellcode:
function RunCmdLine(const CmdLine: string): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  Result := False;
  FillChar(StartupInfo, SizeOf(StartupInfo), 0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOW;

  if CreateProcess(nil, PChar(CmdLine), nil, nil,
    False, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then
  begin
    repeat
    until WaitForSingleObject(ProcessInfo.hProcess, 1) = WAIT_OBJECT_0;
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
    Result := True;
  end
  else
    MessageDLG('Cannot run command line: ' + CmdLine,mtError,[mbOk],0);
end;

Moombas 1. Apr 2020 13:06

AW: CMD / Prozess prüfen
 
@exInfo und Application.ProcessMessages meckert er an @Jumpy, braucht das ein uses?

Delphi.Narium 1. Apr 2020 13:10

AW: CMD / Prozess prüfen
 
Bei mir klappt das als Konsolenanwendung, wenn ich statt des MessageDLG halt
Delphi-Quellcode:
WriteLn('Cannot run command line: ' + CmdLine);
schreibe.

Moombas 1. Apr 2020 13:28

AW: CMD / Prozess prüfen
 
Funktioniert leider nicht.
Delphi-Quellcode:
program Backup;
{$mode Delphi}{$H+}
uses
  ShellAPI, Windows;

{$R *.res}
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  CmdLine: string;
begin
  //ShellExecute(0, nil, PChar('cmd'), PChar('/c wbadmin.exe start backup -quiet -vssCopy -backupTarget:D: -include:C:'), nil, 1);
  CmdLine := 'cmd /c wbadmin start backup -quiet -vssCopy -backupTarget:D: -include:C:';

  FillChar(StartupInfo, SizeOf(StartupInfo), 0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOW;

  if CreateProcess(nil, PChar(CmdLine), nil, nil,
    False, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then
  begin
    repeat
    until WaitForSingleObject(ProcessInfo.hProcess, 1) = WAIT_OBJECT_0;
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end
  else
    WriteLn('Cannot run command line: ' + CmdLine);
  sleep(5000);
end.
Bringt kein Ergebnis/wird nicht gestartet bzw. endet beim "Connot run command line".

Delphi.Narium 1. Apr 2020 13:44

AW: CMD / Prozess prüfen
 
Fehlermeldung?

Bekommst Du die Ausgabe von WriteLn oder einfach nur nix?

Und bei CmdLine wäre es durchaus hilfreich den vollständigen Namen und Pfad des aufzurufenden Programmes anzugeben.

cmd /w hält die Kommandozeile offen, nachdem das per Parameter übergebene Programm beendet wurde. Damit wartet Dein Programm "ewig", bis zum nächsten Stromausfall oder sonst einer "externen Beendigung" der Kommandozeile. Sprich: Kann so nicht funktionieren.

Frage: Muss denn CMD überhaupt aufgerufen werden?

Delphi-Quellcode:
CmdLine := 'PfadZumProgramm\wbadmin.endung start backup -quiet -vssCopy -backupTarget:D: -include:C:';


Beim Programmaufruf über Shellexeute, CreateProcess ... sollte man sich nicht dadrauf verlassen, das Windows das gewünschte schon irgendwie finden wird (das Gewünschte also (mehr oder weniger) zufällig im Pfad ist).

Präzise Angaben helfen deutlich bei der Fehlersuche / Fehlervermeidung.

Moombas 1. Apr 2020 14:11

AW: CMD / Prozess prüfen
 
wbadmin ist eine Windowsanwendung und liegt in System32, kann aber immer per wbadmin aufgerufen werden ohne Pfadangabe.

Der Befehl muss in der Eingabeaufforderung ausgeführt werden.

Ich bekomme die Ausgabe von writeln.

Zitat:

Zitat von Delphi.Narium (Beitrag 1460997)
cmd /w hält die Kommandozeile offen, nachdem das per Parameter übergebene Programm beendet wurde. Damit wartet Dein Programm "ewig", bis zum nächsten Stromausfall oder sonst einer "externen Beendigung" der Kommandozeile. Sprich: Kann so nicht funktionieren.

Stimmt das /w ist eigentlich falsch/veraltet (hatte ich eigentlich schon längst geändert) muss /c sein.
Ändert aber an der Ausführung nix, die CMD würde nur offen bleiben anstatt geschlossen zu werden.

Edit:
Hier trifft meine erste Aussage wohl nicht zu:
Mit
Delphi-Quellcode:
CmdLine := 'C:/Windows/System32/wbadmin.exe start backup -quiet -vssCopy -backupTarget:D: -include:C:';
funktioniert es.

Delphi.Narium 1. Apr 2020 14:53

AW: CMD / Prozess prüfen
 
Ein möglicher Aufruf auf der Kommandozeile ohne Pfadangabe impliziert nicht, dass dies auch aus einem eigenen Programm heraus so sein muss.

Der Aufruf von wbadmin auf der Kommandozeile ohne Pfadangabe heißt nur, dass das Programm in der Umgebung der Kommandozeile im Suchpfad enthalten ist.

Diese Umgebung muss nicht mit der Umgebung Deines Programmes übereinstimmen und schon garnicht mit der Umgebung, die CreateProcess bekommt.

Das WriteLn bedeutet übrigens hier, dass schon CMD nicht gefunden wurde. Auch hier gilt: Vollständiger Pfad- und Dateiname.

Jumpy 1. Apr 2020 15:20

AW: CMD / Prozess prüfen
 
Zitat:

Zitat von Moombas (Beitrag 1460991)
@exInfo und Application.ProcessMessages meckert er an @Jumpy, braucht das ein uses?

Application.ProcessMessages ist in Forms, macht also in deinem Fall vllt. keinen Sinn. exInfo ist aus ShellApi.
Du kannst das ja mal mit einem einachen Befehl testen Notepad.exe oder so. Wenn das geht, klappt ja zumindest der Aufruf mit WaitForSingleObject. Danach muss du halt schauen, wie das mit den Parameter-Liste ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:48 Uhr.
Seite 1 von 2  1 2   

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