如果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;
更一般地说,如何检查是否应关闭手柄?
答案 0 :(得分:10)
如果出现以下情况,您只会返回一个流程句柄:
SEE_MASK_NOCLOSEPROCESS
和如果前两个条件成立但不是第三个,那么您将处理一个值为零的进程句柄。所以你的代码应该是:
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对话满足执行时,将不返回句柄。调用应用程序负责在不再需要时关闭句柄。
最后,请允许我祝贺您认真对待错误检查和泄漏避免的问题。许多开发人员似乎都忽略了这个问题,无论他们告诉了多少次。很高兴您在最近的问题上听过评论并努力改进您的代码。做得好!