How to check if a handle should be closed?

In case 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; 

In general, how can I check if a handle should be closed?

+7
delphi handle
source share
1 answer

Only the process handle is returned to you if:

  • You have enabled SEE_MASK_NOCLOSEPROCESS and
  • Making a function call and
  • The action was resolved by creating a new process.

If the first two conditions are met, but not the third, then you will be processed with a process descriptor with a zero value. Therefore, 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 very pedantic, we could look for error checking on WaitForSingleObject and CloseHandle . Honestly, it’s hard for me to worry in this case. What are the possible failure modes that can be restored from?


You may ask what I mean:

The action was allowed by the creation of a new process.

Well, it is entirely possible that the action of the shell will be resolved by re-cycling the existing process. In this case, the process handle cannot be returned to you. And that puts kibosh on your code, because you have nothing to wait for, let alone to close the handle. You just need to recognize that such scenarios are outside of you.

The documentation has the following:

SEE_MASK_NOCLOSEPROCESS

Use to indicate that the hProcess member receives a process handle. This descriptor is commonly used so that an application can know when a process created with ShellExecuteEx ends. In some cases, for example, when execution is performed 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, let me congratulate you on the serious issues of error checking and leak prevention. So many developers seem to ignore this problem, no matter how many times they are told. It's nice that you listened to comments on the latest issues and tried to improve your code. Well done!

+9
source share

All Articles