[Delphi] Otwieranie EXE+wykrywanie kiedy zakończy się prog

0

Siema
mam problem jak zatrzymać program dopóki aplikacja uruchomiona wcześniej przeze mnie nie zostanie zamknięta

Wiem że jest to możliwe bo kiedyś miałem problem jak to zrobić żeby wykonywał polecenia dalej a nie czekał na zamknięcie aplikacji.

Wiem że istnieją takie polecenia jak:
*ShellExecute
*CreateProcess
*WinExec

Nawet znalazłem kod

var ShellExeInfo: TShellExecuteInfo;
begin
FillChar(ShellExeInfo,SizeOf(ShellExeInfo),0);
with ShellExeInfo do
begin
cbSize:=SizeOf(ShellExeInfo);
fMask:=SEE_MASK_NOCLOSEPROCESS or SEE_MASK_DOENVSUBST or SEE_MASK_FLAG_NO_UI;
Wnd:=Application.Handle;
lpVerb:='open';
lpFile:=PChar('C:\INSTALL\02_WinRar\WinRar.exe');
nShow:=SW_NORMAL;
end;
if ShellExecuteEx(@ShellExeInfo)
then
begin
WaitForInputIdle(ShellExeInfo.hProcess,INFINITE);
WaitForSingleObject(ShellExeInfo.hProcess,INFINITE);
CloseHandle(ShellExeInfo.hProcess);
end; 

w którym jest skrypt który mi jest potrzebny ale ten skrypt zamula FORM

0
uses ShellApi;

function WaitForExec(Filename: String; Visibility: Integer): Cardinal;
var
 AppName    : array[0..512] of Char;
 CurrentDir : array[0..255] of Char;
 WorkDir    : String;
 StartUpInfo: TStartUpInfo;
 ProcessInfo: TProcessInformation;
begin
 StrPCopy(AppName, FileName);
 GetDir(0, WorkDir);
 StrPCopy(CurrentDir, WorkDir);
 FillChar(StartUpInfo, Sizeof(StartUpInfo), #0);
 StartUpInfo.cb          := Sizeof(StartUpInfo);
 StartUpInfo.dwFlags     := STARTF_USESHOWWINDOW;
 StartUpInfo.wShowWindow := Visibility;

 if (not CreateProcess(nil, AppName, nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, CurrentDir, StartUpInfo, ProcessInfo)) then Result := $FFFFFFFF
 else
   begin
    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
   end;
end;

Teraz uruchamiasz program i sprawdzasz

if WaitForExec('C:\program.exe', SW_NORMAL) <> $FFFFFFFF then ShowMessage('Program skończył pracę');
0

Ale ten skrypt który umieściłeś zamula FORM podczas uruchomienia tej aplikacji.

0

To umieść w osobnym wątku i nie pozwól zakończyć aplikacji, przed zakończeniem wykonania wątku.

0

Jeśli ktoś by kiedyś coś takiego potrzebował to tu umieszczę kod

Na formie jest Label i Button.
To jest plik pas:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    function WaitForExec(Filename: String; Visibility: Integer): Cardinal;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


  Topenexe = class(TThread)
  private
    Fsciezka : string;
  protected
    procedure Execute; override;
  public
    constructor Create(sciezka : string);
  end;  

var
  Form1: TForm1;

implementation

{$R *.dfm}
//--------------------------------------------------------------------------
constructor Topenexe.Create(sciezka : string);
begin
inherited Create(False);
Fsciezka := sciezka;
end;
//--------------------------------------------------------------------------
procedure Topenexe.Execute;
begin
Form1.Label1.Caption := 'Program pracuje';
if Form1.WaitForExec(Fsciezka, SW_NORMAL) <> $FFFFFFFF then
    Form1.Label1.Caption := 'Program skończył pracę';
end;
//--------------------------------------------------------------------------
function TForm1.WaitForExec(Filename: String; Visibility: Integer): Cardinal;
var
 AppName    : array[0..512] of Char;
 CurrentDir : array[0..255] of Char;
 WorkDir    : String;
 StartUpInfo: TStartUpInfo;
 ProcessInfo: TProcessInformation;
begin
 StrPCopy(AppName, FileName);
 GetDir(0, WorkDir);
 StrPCopy(CurrentDir, WorkDir);
 FillChar(StartUpInfo, Sizeof(StartUpInfo), #0);
 StartUpInfo.cb          := Sizeof(StartUpInfo);
 StartUpInfo.dwFlags     := STARTF_USESHOWWINDOW;
 StartUpInfo.wShowWindow := Visibility;

 if (not CreateProcess(nil, AppName, nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, CurrentDir, StartUpInfo, ProcessInfo)) then Result := $FFFFFFFF
 else
   begin
    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
   end;
end;
//--------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
temp:string;
begin
temp := ExtractFilePath(Paramstr(0)) + 'exe.exe';
Topenexe.Create(temp);
end;
//--------------------------------------------------------------------------
end.
//--------------------------------------------------------------------------
0

Ładne. Bardzo ładne dziedziczenie po TThread. Przyda się. Dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1