It is required to free the IShellFolder interface returned by SHGetDesktopFolder ? and how?

602 views Asked by At

I am confused. I want to use the function PathToPidlBind from Jedi JCL and I see that they don't release the IShellFolder interfece reurned by SHGetDesktopFolder after using it. Microsoft docs says: "The calling application is responsible for eventually freeing the interface by calling its IUnknown::Release method.". I tried to use DesktopFolder._Release but I get access violation. I'm not sure this is what Microsoft refers to. So how this shold be done right ?

From Jedi JCL:

function PathToPidlBind(const FileName:String; out Folder:IShellFolder): PItemIdList;
var
  Attr, Eaten: ULONG;
  PathIdList: PItemIdList;
  DesktopFolder: IShellFolder;
  Path, ItemName: PWideChar;
begin
  Result:=nil;
  Path:=PWideChar(ExtractFilePath(FileName));
  ItemName:=PWideChar(ExtractFileName(FileName));
  if Succeeded(SHGetDesktopFolder(DesktopFolder)) then begin
    Attr:=0;
    if Succeeded(DesktopFolder.ParseDisplayName(0, nil, Path, Eaten, PathIdList, Attr)) then begin
      if Succeeded(DesktopFolder.BindToObject(PathIdList, nil, IID_IShellFolder, Pointer(Folder))) then begin
        if Failed(Folder.ParseDisplayName(0, nil, ItemName, Eaten, Result, Attr)) then begin
          Folder:=nil;
          Result:=DriveToPidlBind(FileName, Folder);
        end;
      end;
      PidlFree(PathIdList);
    end
    else Result:=DriveToPidlBind(FileName, Folder);
  end;
end;
1

There are 1 answers

3
David Heffernan On BEST ANSWER

COM interfaces are reference counted, and the Delphi compiler generates code to automatically manage the reference counting for you. Each time an interface variable is assigned, Release is called if the variable is not nil, and AddRef is called if the new value is not nil. When the variable goes out of scope, Release is called if not nil.

So it is a mistake to manually release the way you did. You released the interface manually, and then the compiler tried to release it automatically. You have to let the compiler do the work.

If you do wish to release an interface before it goes out of scope, assign nil to it:

DesktopFolder := nil;

But there is no need for you to do that in this example.

The Delphi designers don't want you to explicitly call AddRef and Release, so they named then _AddRef and _Release in order to discourage you from calling these methods directly.