如何检查手柄是否应该关闭?

法布里佐

如果哪个ShellExecuteEx返回false,是否应该关闭该句柄?:

function EditAndWait(const AFileName : string) : boolean;
var
  Info: TShellExecuteInfo;
begin
  FillChar(Info, SizeOf(Info), 0);
  Info.cbSize := SizeOf(Info);
  Info.lpVerb := 'edit';
  Info.lpFile := PAnsiChar(AFileName);
  Info.nShow := SW_SHOW;
  Info.fMask := SEE_MASK_NOCLOSEPROCESS;
  Result := ShellExecuteEx(@Info);
  if(Result) then 
  begin
    WaitForSingleObject(Info.hProcess, Infinite);
    CloseHandle(Info.hProcess);
  end else
  begin
     //should I close the process handle?
  end;
end;

更一般而言,如何检查手柄是否应该关闭?

戴维·赫弗南

仅在以下情况下才返回过程句柄:

  1. 您包括了SEE_MASK_NOCLOSEPROCESS,以及
  2. 函数调用成功,并且
  3. 通过创建新流程解决了该操作。

如果前两个条件成立,但第三个条件成立,则将向您返回值为零的流程句柄。因此,您的代码应为:

Result := ShellExecuteEx(@Info);
if Result and (Info.hProcess<>0) then 
begin
  WaitForSingleObject(Info.hProcess, Infinite);
  CloseHandle(Info.hProcess);
end;

如果我们非常学究,我们可能会在WaitForSingleObject上进行错误检查CloseHandle坦率地说,在这种情况下,我很难为此感到兴奋。可以从哪些故障模式中恢复?


您可能会问我的意思是:

通过创建新流程解决了该操作。

好吧,完全有可能通过回收现有过程来解决shell动作。在这种情况下,可能不会向您返回过程句柄。那样就使代码陷入僵局,因为您没有什么可等待的,不必介意没有关闭的句柄。您只需要接受这样的情况就超出了您的范围。

该文档说:

SEE_MASK_NOCLOSEPROCESS

用于指示hProcess成员接收到进程句柄。此句柄通常用于允许应用程序找出用ShellExecuteEx创建的进程何时终止。在某些情况下,例如通过DDE对话满足执行要求时,将不返回任何句柄。调用应用程序负责在不再需要该句柄时将其关闭。


最后,请允许我祝贺您认真对待错误检查和避免泄漏的问题。如此多的开发人员似乎无视此问题,无论被告知多少次。很高兴您听取了有关最近问题的评论,并努力改进了代码。做得好!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章