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

时间:2016-09-08 14:32:48

标签: delphi handle

如果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 个答案:

答案 0 :(得分:10)

如果出现以下情况,您只会返回一个流程句柄:

  1. 您加入了SEE_MASK_NOCLOSEPROCESS
  2. 函数调用成功,
  3. 通过创建新流程解决了该问题。
  4. 如果前两个条件成立但不是第三个,那么您将处理一个值为零的进程句柄。所以你的代码应该是:

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

    如果我们非常迂腐,我们可能会在WaitForSingleObjectCloseHandle上查找错误。坦率地说,在这种情况下,我发现很难对此感到兴奋。有哪些可能的故障模式可以从中恢复?

    你可能会问我的意思:

      

    通过创建新流程解决了该问题。

    嗯,完全有可能通过重新循环现有流程来解决shell操作。在这种情况下,您可能不会返回进程句柄。这会让你的代码变得无比,因为你没有什么值得等待的,不用担心没有关闭的句柄。你只需要接受这种情况超出你的范围。

    文档可以这样说:

      

    SEE_MASK_NOCLOSEPROCESS

         

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

    最后,请允许我祝贺您认真对待错误检查和泄漏避免的问题。许多开发人员似乎都忽略了这个问题,无论他们告诉了多少次。很高兴您在最近的问题上听过评论并努力改进您的代码。做得好!