Solved

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

Posted on 2013-02-05
4
569 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
  • 2
4 Comments
 
LVL 23

Expert Comment

by:tailoreddigital
Comment Utility
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
Comment Utility
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 500 total points
Comment Utility
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
Comment Utility
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Here we come across an interesting topic of coding guidelines while designing automation test scripts. The scope of this article will not be limited to QTP but to an overall extent of using VB Scripting for automation projects. Introduction Now…
Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
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 seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

728 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now