【问题标题】:Close, Destroy MainForm cleanly after shellexecute - Delphi关闭,在 shellexecute 之后彻底销毁 MainForm - Delphi
【发布时间】:2014-07-04 12:57:37
【问题描述】:

我必须为 exe 文件开发一个启动器,但我在关闭主窗体时遇到了一些问题。

我想保持打开可执行文件但关闭表单。 我成功执行了应用程序,执行了 .exe 并在 .exe 打开后“关闭”了表单。这几乎是我想要的,但 launcher.exe 在 Windows 任务管理器中仍然处于活动状态。

这是执行.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;

这是关闭的自定义程序:

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;

我编写了这个自定义过程,因为有时我只想在单击 X 窗口的按钮时将表单隐藏在参数函数中的托盘图标中。所以,不要关心第一个条件“if Bclose then”。

我确保自己释放了我在 FormCreate 中创建的 FormDestroy 中的所有对象,但无事可做,进程持续存在......

如果您能帮助我,或者您看看我的问题,我将不胜感激。 提前谢谢你..

【问题讨论】:

  • 您必须使用CreateProcess 才能在您启动另一个进程后关闭host 应用程序。
  • Application.Terminate 应该完成它。显示所有ShellExecute 代码是没有意义的,因为它与实际问题无关(尽管这样做确实表明您泄漏了进程句柄)。请尝试将其减少到说明问题所需的最低限度。这对每个人都有帮助,尤其是你。在Self 上调用Free 几乎总是一场灾难。这样做,你就会把自己画成一个真正的洞。想想当Free 返回时会发生什么?
  • 感谢您的快速回答,并为我的英语不好感到抱歉。我刚刚使用 [code]CreateProcess 进行了测试,但出现了同样的问题。我还删除了 [code]Free,但它并没有解决进程在后台运行的事实。

标签: forms delphi destroy forceclose


【解决方案1】:

这是一个小型的 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;

问题在于您在程序中调用了Free,不要那样做。

【讨论】:

  • 您还复制了问题中的句柄泄漏。删除SEE_MASK_NOCLOSEPROCESS,或关闭手柄。对ShellExecuteEx 进行一些错误检查会很好。用Win32Check包裹起来。
  • 没关系。我只是为了任何读者而添加这个。你确实解决了关键问题。
  • 我从不需要在 MainForm 中设置 CloseAction。并且CanClose 默认为true
  • 实际上有问题的代码似乎没有使用 OnClose。我不明白你为什么要建议实施它。
  • David Heffernan,我已经测试了您的建议,但无事可做,它仍然在后台进程中激活。 Rufo 爵士,是的,CanClose 被认为是默认的。我删除了它。
猜你喜欢
  • 1970-01-01
  • 2012-01-06
  • 2012-12-06
  • 2017-03-07
  • 2020-01-10
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多