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 =:)
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 =:)
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 =:(
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
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
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 =:(
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Couple times ago I played with recycle bin folder.
function SHQueryRecycleBin(pszrtoot path:pchar ;QUERYRBIN FO:pshquer yrbinfo):i nteger;std call;
external 'shell32' name 'SHQueryRecycleBinA';
procedure TForm1.Button1Click(Sender : TObject);
var rbinfo:SHQUERYRBINFO;
begin
rbinfo.cbSize:=sizeof(rbin fo);
rbinfo.i64Size:=0;
rbinfo.i64NumItems:=0;
SHQueryRecycleBin('C:\',@r binfo);
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 .
function SHQueryRecycleBin(pszrtoot
external 'shell32' name 'SHQueryRecycleBinA';
procedure TForm1.Button1Click(Sender
var rbinfo:SHQUERYRBINFO;
begin
rbinfo.cbSize:=sizeof(rbin
rbinfo.i64Size:=0;
rbinfo.i64NumItems:=0;
SHQueryRecycleBin('C:\',@r
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(S ender: 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(SHGetDesktopFolde r(DeskFold er));
OleCheck(SHGetSpecialFolde rLocation( Applicatio n.Handle, CSIDL_BITBUCKET, RecycleIDL));
DeskFolder.BindToObject(Re cycleIDL, nil, IShellFolder, RecycleBin);
if RecycleIDL <> nil then
ShellMalloc.Free(RecycleID L);
OleR := RecycleBin.EnumObjects(App lication.H andle, 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.GetDisplayNameO f(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.u Offset - SizeOf(NextId.mkid.cb)];
SetString(FileName1, Pstr, NextId.mkid.cb - StrRet.uOffset);
end;
STRRET_WSTR: FileName1 := StrRet.pOleStr;
end;
ListBox1.Items.Add(FileNam e1);
{the FileName1 will have the file in the recycle}
SetLength(PIidListA,IdList Num);
PIidListA[IdListNum-1] := NextId;
Inc(IdListNum);
end; //IsThere
end; // while
if IdListNum > 1 then
try
OleR := RecycleBin.GetUIObjectOf(A pplication .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
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(S
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(SHGetDesktopFolde
OleCheck(SHGetSpecialFolde
DeskFolder.BindToObject(Re
if RecycleIDL <> nil then
ShellMalloc.Free(RecycleID
OleR := RecycleBin.EnumObjects(App
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.GetDisplayNameO
case StrRet.uType of
STRRET_CSTR: SetString(FileName1, StrRet.cStr, lStrLen(StrRet.cStr));
STRRET_OFFSET:
begin
Pstr := @NextId.mkid.abID[StrRet.u
SetString(FileName1, Pstr, NextId.mkid.cb - StrRet.uOffset);
end;
STRRET_WSTR: FileName1 := StrRet.pOleStr;
end;
ListBox1.Items.Add(FileNam
{the FileName1 will have the file in the recycle}
SetLength(PIidListA,IdList
PIidListA[IdListNum-1] := NextId;
Inc(IdListNum);
end; //IsThere
end; // while
if IdListNum > 1 then
try
OleR := RecycleBin.GetUIObjectOf(A
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(
{this does the Recycle Context menu Delete}
end;
finally
if IdListNum > 1 then
for i := 0 to High(PIidListA) do
ShellMalloc.Free(PIidListA
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...
Regards, Madshi.
P.S: Nothing precious to add to all the comments here...
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 =:)
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 =:)
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 =:)
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.
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.
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
http://www.efg2.com/Lab/Library/Delphi/IO/Files.htm
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 =:)
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
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
begin
SHEmptyRecycleBin(Applicat
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 :)