0
votes

I have to develop a launcher for an exe file but I have some trouble with the closing of the mainform.

I want to keep open the executable but close the form. I achieved success with the execution of the application, the .exe is executed and the form is "closed" after the .exe is open. It is almost what I wanted but the launcher.exe is still active in the windows Task Manager.

This is the procedure for executing the .exe :

procedure TForm2.LancerVersion(aExe: String);
var
  SEInfo: TShellExecuteInfo;

begin
  FillChar(SEInfo, SizeOf(SEInfo), 0);
  SEInfo.cbSize := SizeOf(TShellExecuteInfo);
  with SEInfo do
  begin 
    fMask := SEE_MASK_NOCLOSEPROCESS;
    Wnd := Application.Handle;
    lpFile := PChar(aExe);
    nShow := SW_SHOWNORMAL;
  end;    
  ShellExecuteEx(@SEInfo);
  if Blight then
   begin
    free;
    Close; **//HERE I WOULD LIKE TO CLOSE CLEANLY MY FORM**
   end 
  else
   hide;
end;

This is the custom procedure for the closing :

procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
    if BClose then
    begin
      Canclose := false;
      Bshow := false;
    end;
    Canclose := true; **//IT GOES HERE AFTER CLOSE IS CALLED**
end;

I have written this custom procedure because sometimes I just want to hide the form in the trayicon in function of a parameter when we click on the X window's button. So, don't care about the first condition "if Bclose then".

I ensured myself to free all my object in the FormDestroy that I've created in the FormCreate but nothing to do, the processus persist...

I'll appreciate if you could help me or just if you look at my problem. Thank you in advance..

1
You have to use CreateProcess to be able to close host application after you start another process from it. - LightBulb
Application.Terminate should get it done. Showing all the ShellExecute code is pointless since it has nothing to do with the actual problem (although doing so does reveal that you leak a process handle). Please try to cut this down to the minimum needed to illustrate the problem. That helps everyone, most especially you. Calling Free on Self is pretty much always a disaster. Do that and you paint yourself into a real hole. Think about what happens when Free returns? - David Heffernan
Thank you for your fast answers and sorry for my bad english. I've just tested with the [code]CreateProcess but the same problem appears. I also removed [code]Free but it didn't solve the fact that the processus runs in background. - BzhProg

1 Answers

2
votes

Here is a small working SSCCE:

procedure TForm1.Button1Click(Sender: TObject);

var
  SEInfo: TShellExecuteInfo;
  ExecuteFile: string;

begin
  ExecuteFile := 'notepad.exe';
  FillChar(SEInfo, SizeOf(SEInfo), 0);
  SEInfo.cbSize := SizeOf(TShellExecuteInfo);
  with SEInfo do
  begin
    Wnd := Application.Handle;
    lpFile := PChar(ExecuteFile);
    nShow := SW_SHOWNORMAL;
  end;
  Win32Check(ShellExecuteEx(@SEInfo));
  Close;
end;

The problem lies in the fact that you are calling Free in your procedure, don't do that.