Link to home
Start Free TrialLog in
Avatar of TheNeil
TheNeil

asked on

Recycle Bin

Couple of questions actually but they're all Recycle Bin related so tough:

1. How do I go about emptying the Recycle Bin in code under Win 9X AND NT?
2. How do I find out details of what's IN the Recycle Bin (i.e. no files, sizes etc.)?

Anybody got any ideas?

The Neil =:)
Avatar of inthe
inthe

hi,
from paq:

to empty recycle bin use :

{$EXTERNALSYM SHEmptyRecycleBin}
function SHEmptyRecycleBin(hwnd: HWND; pszRootPath: PChar; dwFlags: DWord): HResult; stdcall;

const
SHERB_NOCONFIRMATION = 1;
SHERB_NOPROGRESSUI = 2;
SHERB_NOSOUND = 4;

implementation

{$R *.DFM}

{$EXTERNALSYM SHEmptyRecycleBin}
function SHEmptyRecycleBin; external 'shell32.dll' name 'SHEmptyRecycleBinA';

procedure TForm1.Button1Click(Sender: TObject);
begin
SHEmptyRecycleBin(Application.Handle, nil, SHERB_NOCONFIRMATION);
end;



i havent got listing files to work properly before but i remember someone posting some code here once that was half way there ..

listening for fursther info myself :)
Avatar of TheNeil

ASKER

Weeeellllll, that looks suspciously like code that supposedly works under Win 9X but under NT I get 'Unable to find SHEmptyRecycleBinA in Shell32.dll' when I run it

Sorry =:(
Hi TheNeil, Inthe

found some API calls utilized in vb (sorry)

http://www.mvps.org/vbnet/index.html?code/system/shrecycle.htm
http://www.mvps.org/vbnet/code/shell/shfileopadv.htm

Hope that you can use some of it, since the calls should be essentially the same

:O)Bruintje
Avatar of TheNeil

ASKER

Hi Bruintje,

Just as with InThe's answer I get the same 'Unable to find <X> in Shell32.dll' error when I run the code. Under Win 9X this might be fine but this has got to work under NT as well and as that's what I'm working under today, it's a none starter

Good suggestion though

The Neil =:(
ASKER CERTIFIED SOLUTION
Avatar of Brian Mulder
Brian Mulder
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Couple times ago I played with recycle bin folder.

function SHQueryRecycleBin(pszrtootpath:pchar;QUERYRBINFO:pshqueryrbinfo):integer;stdcall;
external 'shell32' name 'SHQueryRecycleBinA';

procedure TForm1.Button1Click(Sender: TObject);
var rbinfo:SHQUERYRBINFO;
begin
  rbinfo.cbSize:=sizeof(rbinfo);
  rbinfo.i64Size:=0;
  rbinfo.i64NumItems:=0;
  SHQueryRecycleBin('C:\',@rbinfo);
  Label1.Caption:=intTostr(  rbinfo.cbSize);
  Label2.Caption:=inttostr ( rbinfo.i64Size  );
  Label3.Caption:=inttostr(   Rbinfo.i64NumItems);
end;

Label1 mean size of structure
Label2 mean size of recycle bin
Label3 mean number of items

Tested now under XP Pro .
Then I was able to read the each file name and the original location but look like XP have changed the structure of Info2 file .
i was suprised as its working here on nt no problems then i seen Bruintje  comments ,without a version of shell32.dll newer than 4.71 i dont know how your supposed to empty it,the ie4 active desktop update will update it to 4.71 if you want to install it (if you can still get it :)
interesting :)
I tried the SHEmptyRecycleBin( ) and it worked on one puter and not on another, but I forget which OS versions.
Here's some code that I have used to get the contents of the recycle and I added a contex menu delete to it.


implementation

{$R *.DFM}

uses ShlObj, ComObj, ActiveX;

procedure TForm1.sbut_EmptyReClick(Sender: TObject);
var
DeskFolder, RecycleBin: IShellFolder;
RecycleIDL, NextId: PItemIDList;
OleR: HResult;
ShellMalloc: IMalloc;
EnumList: IENUMIDLIST;
IsThere: ULONG;
PIidListA: Array of Pointer;
IdListNum: Cardinal;
i: Integer;
StrRet: TStrRet;
FileName1: String;
Pstr: PChar;
CmInfo: CMINVOKECOMMANDINFO;
ContextMenu: IContextMenu;
begin
IdListNum := 1;
if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
  begin
  OleCheck(SHGetDesktopFolder(DeskFolder));
  OleCheck(SHGetSpecialFolderLocation(Application.Handle, CSIDL_BITBUCKET, RecycleIDL));
  DeskFolder.BindToObject(RecycleIDL, nil, IShellFolder, RecycleBin);
  if RecycleIDL <> nil then
    ShellMalloc.Free(RecycleIDL);
  OleR := RecycleBin.EnumObjects(Application.Handle, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN, EnumList);
  if SUCCEEDED(OleR) then
    begin //OleR
    ListBox1.Clear;
    while (EnumList.Next(1, NextId, IsThere)=S_OK) do
      begin //while
      if IsThere > 0 then
        begin // IsThere
        RecycleBin.GetDisplayNameOf(NextId, SHGDN_NORMAL, StrRet);
        case StrRet.uType of
          STRRET_CSTR: SetString(FileName1, StrRet.cStr, lStrLen(StrRet.cStr));
          STRRET_OFFSET:
            begin
            Pstr := @NextId.mkid.abID[StrRet.uOffset - SizeOf(NextId.mkid.cb)];
            SetString(FileName1, Pstr, NextId.mkid.cb - StrRet.uOffset);
            end;
          STRRET_WSTR: FileName1 := StrRet.pOleStr;
          end;
        ListBox1.Items.Add(FileName1);
        {the FileName1 will have the file in the recycle}
        SetLength(PIidListA,IdListNum);
        PIidListA[IdListNum-1] := NextId;
        Inc(IdListNum);
        end; //IsThere
      end; // while
    if IdListNum > 1 then
    try
      OleR := RecycleBin.GetUIObjectOf(Application.Handle, IdListNum-1, PItemIDList(PIidListA[0]), IID_IContextMenu, nil, ContextMenu);
      if SUCCEEDED(OleR) then
        begin
        FillChar(CmInfo, SizeOf(CmInfo), 0);
        with CmInfo do
          begin
          cbSize:= sizeof (CMINVOKECOMMANDINFO);
          fMask:= 0;
          hwnd:= Application.Handle;
          lpVerb:= PChar('delete');
          lpParameters:= nil;
          lpDirectory:= nil;
          nShow:= SW_SHOWDEFAULT;
          dwHotKey:= 0;
          hIcon:= 0;
          end;

        ContextMenu.InvokeCommand(CmInfo);
        {this does the Recycle Context menu Delete}
        end;
   finally
   if IdListNum > 1 then
   for i := 0 to High(PIidListA) do
   ShellMalloc.Free(PIidListA[i]);
   end;
   end; // OleR
  end;

end;

- - - - - - - - - - - - - - - - -
it may could be optimized some, but it worked for me. If it's unclear, ask questions.
Wes
Wow, Wes, I'm surprised to see such complicated code without any memory/resource leak, well done! That's not what I'm used to see here...   :-)

Regards, Madshi.

P.S: Nothing precious to add to all the comments here...
Avatar of TheNeil

ASKER

Bruintje

The out of date DLL looks to be the root of the problem BUT how do I update it? Under NT it won't let me and even though I'm using IE 5.5 (and re-sinstalled it to make sure) on NT4 (service pack 6), Shell32.dll stubbornly stays at version 4.00 (which explains why it can't find entry points for the Recycle Bin routines) - Any ideas?

The Neil =:)
Avatar of TheNeil

ASKER

Bruintje

The out of date DLL looks to be the root of the problem BUT how do I update it? Under NT it won't let me and even though I'm using IE 5.5 (and re-sinstalled it to make sure) on NT4 (service pack 6), Shell32.dll stubbornly stays at version 4.00 (which explains why it can't find entry points for the Recycle Bin routines) - Any ideas?

The Neil =:)
Only IE4 had the option to update the shell. IE5 and IE6 don't have this option anymore...   :-/

Read it here:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/versions.asp

Regards, Madshi.
Am not sure about this but could'nt you just delete the files from the folder C:\Recycled or whichever the drive is if you don't have a version of shell32.dll newer than 4.71

I seem to remember having to do something like this a while back. It should work as long as the recycle bin is setup to recycle files.
Also just found a link which may be of interest to you:

http://www.efg2.com/Lab/Library/Delphi/IO/Files.htm
Avatar of TheNeil

ASKER

Bruintje

This is definitely the answer and it seems that the IT people where I work made sure that Shell32.dll was always reset to v4.00 on reboot so even installing/replacing it wouldn't add the recycle bin functionality. Why they do this I don't know but what I do know is that this works now (after much shouting)

Thanks for everyone's help

The Neil =:)
Wow, thank you very much and all the others for contributing.....learned a lot again just for hopping in