是的,madExcept是正确的,这是可以预料的,因为它的质量非常高。这确实是您使用的代码中的缺陷。它看起来像这样:
function CreateRootFolder(RootFolder: TShellFolder; OldRoot : TRoot;
var NewRoot: TRoot): TShellFolder;
var
P: PWideChar;
NewPIDL: PItemIDList;
NumChars,
Flags,
HR: LongWord;
ErrorMsg : string;
begin
HR := S_FALSE;
if GetEnumValue(TypeInfo(TRootFolder), NewRoot) >= 0 then
begin
HR := SHGetSpecialFolderLocation(
0,
nFolder[GetCSIDLType(NewRoot)],
NewPIDL);
end
else if Length(NewRoot) > 0 then
begin
if NewRoot[Length(NewRoot)] = ':' then NewRoot := NewRoot + '\';
NumChars := Length(NewRoot);
Flags := 0;
P := StringToOleStr(NewRoot);
HR := DesktopShellFolder.ParseDisplayName(0, nil, P, NumChars, NewPIDL, Flags);
end;
if HR <> S_OK then
begin
{ TODO : Remove the next line? }
// Result := RootFolder;
ErrorMsg := Format( SErrorSettingPath, [ NewRoot ] );
NewRoot := OldRoot;
raise Exception.Create( ErrorMsg );
end;
Result := CreateRootFromPIDL(NewPIDL);
if Assigned(RootFolder) then RootFolder.Free;
end;
NewPIDL
的责任在调用方。代码本身不会销毁它。可以从文档中看到这一点:
修改函数的最后部分,使其如下所示:Result := CreateRootFromPIDL(NewPIDL);
if Assigned(RootFolder) then RootFolder.Free;
CoTaskMemFree(NewPIDL);
我可以确认已经测试了这个更改。我测试了原始代码并复现了您报告的泄漏情况。然后按上述描述更改了代码,madExcept没有报告泄漏。
你无法达到相同的效果意味着你没有执行修改后的代码。也许你正在使用运行时包,并且没有重新编译修改后的代码。或者可能有另一种解释。不管怎样,对我来说完全清楚,你未能消除泄漏是因为你仍在运行原始未经修改的代码。