How to check if an handle should be closed?

妖精的绣舞 提交于 2019-12-08 17:30:16

问题


In case which ShellExecuteEx returns false, should the handle be closed?:

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;

More generally, how can I check if an handle should be closed?


回答1:


You are only returned a process handle if:

  1. You included SEE_MASK_NOCLOSEPROCESS, and
  2. The function call succeeded, and
  3. The action was resolved by creating a new process.

In case the first two conditions hold, but not the third, then you will be handled back a process handle with value zero. So your code should be:

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

If we were being very pedantic we might look for error checking on WaitForSingleObject and CloseHandle. Frankly though, I find it hard to get excited about that in this instance. What are the possible failure modes that could be recovered from?


You might well ask what I mean by:

The action was resolved by creating a new process.

Well, it's entirely possible for a shell action to be resolved by re-cycling an existing process. In which case you may not be returned a process handle. And that puts the kibosh on your code because you have nothing to wait on, never mind no handle to close. You'll just have to accept that such scenarios are beyond you.

The documentation has this to say:

SEE_MASK_NOCLOSEPROCESS

Use to indicate that the hProcess member receives the process handle. This handle is typically used to allow an application to find out when a process created with ShellExecuteEx terminates. In some cases, such as when execution is satisfied through a DDE conversation, no handle will be returned. The calling application is responsible for closing the handle when it is no longer needed.


Finally, may I congratulate you on taking seriously the issues of error checking and leak avoidance. So many developers seem to ignore this issue, no matter how many times they are told. It's nice that you have listened to comments at recent questions and made the effort to improve your code. Well done!



来源:https://stackoverflow.com/questions/39393696/how-to-check-if-an-handle-should-be-closed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!