Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to check if the recycle bin is empty in DElphi.

Posted on 2013-02-05
4
Medium Priority
?
612 Views
Last Modified: 2013-02-06
I am using Delphi 2010 on a Win 7 64 bit machine and I need to check if the recycle bin is empty. I picked up the following from the web

function RecycleBinIsEmpty: Boolean;
const
  CLSID_IRecycleBin: TGUID = (D1: $645FF040; D2: $5081; D3: $101B;
    D4: ($9F, $08, $00, $AA, $00, $2F, $95, $4E));
var
  EnumIDList: IEnumIDList;
  FileItemIDList: PItemIDList;
  ItemCount: ULONG;
  RecycleBin: IShellFolder;
begin
  CoInitialize(nil);
  OleCheck(CoCreateInstance(CLSID_IRecycleBin, nil, CLSCTX_INPROC_SERVER or
    CLSCTX_LOCAL_SERVER, IID_IShellFolder, RecycleBin));
  RecycleBin.EnumObjects(0,
    SHCONTF_FOLDERS or
    SHCONTF_NONFOLDERS or
    SHCONTF_INCLUDEHIDDEN,
    EnumIDList);
  Result := EnumIDList.Next(1, FileItemIDList, ItemCount) <> NOERROR;
  CoUninitialize;
end;

but no matter what the result always indicates the Recycle Bin is empty even when I have checked that it is not empty. I even tried checking the number of items in the recycle bin using

var
  rbinfo: SHQUERYRBINFO;
  Retval: Integer;
begin
  rbinfo.cbSize := SizeOf(rbinfo);

  Retval := SHQueryRecycleBin('',@rbinfo);

But Retval always ends up as 0.

Has anyone got any idea what is going wrong?
0
Comment
Question by:Rodbach
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 23

Expert Comment

by:tailoreddigital
ID: 38856975
I know nothing about Delphi, but in looking at code from the web, your code has a slight difference when compared to the code from the web,

YOUR CODE
Result := EnumIDList.Next(1, FileItemIDList, ItemCount) <> NOERROR;
                                                                                                                    ^^
                                                                                                                    ||

FROM THE WEB
Result := EnumIDList.Next(1, FileItemIDList, ItemCount)  NOERROR;


I don't know if it makes any difference, but i thought i'd point it out.
0
 
LVL 9

Expert Comment

by:rinfo
ID: 38858797
try SHQueryRecycleBin in shell32.

function RecycleBinInfo(const Drive: Char; out BinSize, FileCount: Int64):
  Boolean;
type
  // structure passed to SHQueryRecycleBin to get information about recyle bin
  TSHQueryRBInfo = packed record
    cbSize: Integer;    // size of structure
    i64Size: Int64;     // size of recycle bin
    i64NumItems: Int64; // number of items in recycle bin.
  end;
  PSHQueryRBInfo = ^TSHQueryRBInfo;
  // function prototype for SHQueryRecycleBin (prototypes Unicode version when
  // PChar = PWideChar and ANSI version when PChar = PAnsiChar
  TSHQueryRecycleBin = function(RootPath: PChar; Query: PSHQueryRBInfo): 
    Integer; stdcall;
const
  {$IFDEF UNICODE}
  cSHQueryRecycleBin = 'SHQueryRecycleBinW';  // Unicode SHQueryRecycleBin fn
  {$ELSE}
  cSHQueryRecycleBin = 'SHQueryRecycleBinA';  // ANSI SHQueryRecycleBin fn
  {$ENDIF}
  cShell32 = 'shell32.dll';                   // SHQueryRecycleBin's DLL
var
  SHQueryRecycleBin: TSHQueryRecycleBin;  // reference to SHQueryRecycleBin fn
  Shell32: Windows.THandle;               // handle to shel32.dll
  SHQueryRBInfo: TSHQueryRBInfo;          // structure receive recyle bin info
  RootDir: string;                        // directory we are getting info for
  PRootDir: PChar;                        // pointer to root dir or nil
begin
  // Intialise to assume failure
  Result := False;
  BinSize := 0;
  FileCount := 0;
  // Attempt to load required SHQueryRecycleBin function from DLL
  Shell32 := SysUtils.SafeLoadLibrary(cShell32);
  if Shell32 <> 0 then
  begin
    @SHQueryRecycleBin := Windows.GetProcAddress(Shell32, cSHQueryRecycleBin);
    if Assigned(@SHQueryRecycleBin) then
    begin
      // Set structure size before calling SHQueryRecycleBin
      SHQueryRBInfo.cbSize := SizeOf(SHQueryRBInfo);
      // Create pointer to required drive (nul to get all drives)
      {$IFDEF UNICODE}
      if SysUtils.CharInSet(UpCase(Drive), ['A'..'Z']) then
      {$ELSE}
      if UpCase(Drive) in ['A'..'Z'] then
      {$ENDIF}
      begin
        RootDir := UpCase(Drive) + ':\';
        PRootDir := PChar(RootDir);
      end
      else
        PRootDir := nil;
      // Get recycle info
      Result := SHQueryRecycleBin(PRootDir, @SHQueryRBInfo) = 0;
      if Result then
      begin
        // Success: pass info back through params
        BinSize := SHQueryRBInfo.i64Size;
        FileCount := SHQueryRBInfo.i64NumItems;
      end;
    end;
  end;
end;

Open in new window

0
 
LVL 9

Accepted Solution

by:
rinfo earned 2000 total points
ID: 38858818
This is the complete example i tried and tested.
procedure TForm1.Button1Click(Sender: TObject);
var Binsize,FileCount:Int64;
begin
  RecycleBinInfo(  'C',BinSize, FileCount);
end;

function TForm1.RecycleBinInfo(const Drive: Char; out BinSize, FileCount: Int64):
  Boolean;
type
  // structure passed to SHQueryRecycleBin to get information about recyle bin
  TSHQueryRBInfo = packed record
    cbSize: Integer;    // size of structure
    i64Size: Int64;     // size of recycle bin
    i64NumItems: Int64; // number of items in recycle bin.
  end;
  PSHQueryRBInfo = ^TSHQueryRBInfo;
  // function prototype for SHQueryRecycleBin (prototypes Unicode version when
  // PChar = PWideChar and ANSI version when PChar = PAnsiChar
  TSHQueryRecycleBin = function(RootPath: PChar; Query: PSHQueryRBInfo):
    Integer; stdcall;
const
  {$IFDEF UNICODE}
  cSHQueryRecycleBin = 'SHQueryRecycleBinW';  // Unicode SHQueryRecycleBin fn
  {$ELSE}
  cSHQueryRecycleBin = 'SHQueryRecycleBinA';  // ANSI SHQueryRecycleBin fn
  {$ENDIF}
  cShell32 = 'shell32.dll';                   // SHQueryRecycleBin's DLL
var
  SHQueryRecycleBin: TSHQueryRecycleBin;  // reference to SHQueryRecycleBin fn
  Shell32: Windows.THandle;               // handle to shel32.dll
  SHQueryRBInfo: TSHQueryRBInfo;          // structure receive recyle bin info
  RootDir: string;                        // directory we are getting info for
  PRootDir: PChar;                        // pointer to root dir or nil
begin
  // Intialise to assume failure
  Result := False;
  BinSize := 0;
  FileCount := 0;
  // Attempt to load required SHQueryRecycleBin function from DLL
  Shell32 := SysUtils.SafeLoadLibrary(cShell32);
  if Shell32 <> 0 then
  begin
    @SHQueryRecycleBin := Windows.GetProcAddress(Shell32, cSHQueryRecycleBin);
    if Assigned(@SHQueryRecycleBin) then
    begin
      // Set structure size before calling SHQueryRecycleBin
      SHQueryRBInfo.cbSize := SizeOf(SHQueryRBInfo);
      // Create pointer to required drive (nul to get all drives)
      {$IFDEF UNICODE}
      if SysUtils.CharInSet(UpCase(Drive), ['A'..'Z']) then
      {$ELSE}
      if UpCase(Drive) in ['A'..'Z'] then
      {$ENDIF}
      begin
        RootDir := UpCase(Drive) + ':\';
        PRootDir := PChar(RootDir);
      end
      else
        PRootDir := nil;
      // Get recycle info
      Result := SHQueryRecycleBin(PRootDir, @SHQueryRBInfo) = 0;
      if Result then
      begin
        // Success: pass info back through params
        BinSize := SHQueryRBInfo.i64Size;
        FileCount := SHQueryRBInfo.i64NumItems;
        showMessage(intToStr(FileCount));
      end;
    end;
  end;
end;

Open in new window

0
 

Author Comment

by:Rodbach
ID: 38860305
tailoreddigital - the web code is wrong that line needs the '<>' in order to compile. The right hand side of the assignment needs to evaluate to a Boolean value. But well spotted.

rinfo - your example works perfectly and I have awarded you the points. many thanks
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
The SignAloud Glove is capable of translating American Sign Language signs into text and audio.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question