Link to home
Start Free TrialLog in
Avatar of dmetzler
dmetzler

asked on

how to empty the recycle bin?

How can I pragmatically empty the recycle bin?

I have been able to count items in the bin by:

SHGetDesktopFolder() and SHGetSpecialFOlderLocation().  I then use BindToObject() to bind the desktop to the recycle bin and EnumObjects() with the IEnumIDList interface.

But how do I empty the recycle bin?
Avatar of connex
connex
Flag of Germany image

Never did it myself, but i believe SHFileOperation() should
do it.

connex


Never did it myself, but i believe SHFileOperation() should
do it.

connex


Avatar of dmetzler
dmetzler

ASKER

I believe that will allow items to be placed in the recycle bin, but that will not handle emptying the recycle bin.

Don
You need to call the SHGetSpecialFolderPath function with CSIDL_BITBUCKET as the nFolder argument. This function will give you the actual recycle bin folder. Once you have the folder name, you can delete the files as you normally would. I personally use _unlink when deleting files, but there are also Win32 functions to do the same thing.

Tom
Ok. I've done some more research. I think the following api is what you need...

SHEmptyRecycleBin

You can find the documentation on how to use it at...

http://www.eu.microsoft.com/msdn/sdk/inetsdk/help/itt/Shell/Functions/SHEmptyRecycleBin.htm

HTH,
Tom
>>You need to call the SHGetSpecialFolderPath function with CSIDL_BITBUCKET as the nFolder argument.

Is this available in all versions of SHELL32.DLL?  Or is this new only to IE 4.0?  I need a solution for any version of Win95/NT if possible.
Yet, the SHEmptyRecycleBin function must be used with the lastest shell32.dll and ie 4.
Any way to do it through COM/OLE?
The SHEmptyRecycleBin() is not guaranteed to be a part of all implementations of Windows/IE.  I need a solution which using the Shell functions (via COM/OLE) to do this.
COM is nothing more than a binary interface standard. It doesn't automatically make a given function exist on a given platform if that function is not implemented to begin with. In other words, SHEmptyRecycleBin is a shell function in that it exists in the latest version of shell32.dll. Whether you use this exported function in the standard manner of implicitly loading the dll and calling its function or whether you call a com interface that wraps the same function, the point is that the underlying shell32.dll has to implement the function.

Are you certain that is the case?  I believe there is a lot of Windows functionality is available via COM where there are no direct exported API calls.

Due to the fact that Windows is able to access the recycle bin and empty it and that the recycle bin is nothing more than an ActiveX shell extension, I would presume that COM would work over SHEmptyRecycleBin() no matter which version of Windows95 is being used.

What I am really looking for is how to get at the IContextMenu for the recycle bin via COM to the shell and issue a command 0x72.

FINALLY!!! I think I just tracked down what you need...

1. Call CoCreateInstance using the recycle bin's
CLSID
2. Use the IShellExtInit interface to initialize it with the recycle bin's pidl
3. Obtain an IContextMenu interface and invoke command 0x72.

I guess it would have helped had I mentioned what the clsid was,huh ;)

HKEY_CLASSES_ROOT\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}

What does this code look like, exactly?  I found something similar through DejaNews, but nothing specific as far as implementation.

1. Call CoCreateInstance using the recycle bin's
CLSID
2. Use the IShellExtInit interface to initialize it with the recycle bin's pidl
3. Obtain an IContextMenu interface and invoke command 0x72.
dmetzler,

Sorry I couldn't be more specific, but I've never done it either. However, I've played with it for a while and have done the following. I found the recycle bin's clsid, figured out how to create the pidl for the recycle bin and was able to get the IShellExtInit::Initialize to work. Now, i'm trying to get the IContextMenu so that I can call its InvokeCommand. However, its 2 and I have to be up by 5:30 so I'll try this some more tomorrow.

Tom

Tom,

Thanks - I'll double the points for you if you can this.

Don
BTW, if I ever do get this 72 command to work, won't the end-user see a delete confirmation dialog? Is that not a problem?
Hmmm...I don't know about that - you could be correct.  However, I think I can turn that off (at least temporarily) in the registry.
ASKER CERTIFIED SOLUTION
Avatar of tma050898
tma050898
Flag of United States of America 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
I cleaned up the code a little bit. I still had a bunch of "orphan code" from the different approaches I had tried ;)

Although this works to some extent, I still have 2 bugs that I am chasing down...

void CEmptyRecycleBinDlg::OnOk()
{
 BOOL bSuccess = FALSE;
 HRESULT hr;

 ::CoInitialize(NULL);

 // Get recycle bin's pidl
 LPITEMIDLIST psyspidl = NULL;
 hr = SHGetSpecialFolderLocation(NULL, CSIDL_BITBUCKET, &psyspidl);
 if (SUCCEEDED(hr))
 {
  // Get a IContextMenu ptr interface for the Recyle Bin
  IContextMenu* pIContextMenu = NULL;
  HRESULT hr = ::CoCreateInstance(CLSID_RecyleBin,
   NULL,
   CLSCTX_INPROC_SERVER,
   IID_IContextMenu,
   (void**)&pIContextMenu
  );

  if (SUCCEEDED(hr))
  {
   // Send the "Empty Recyle Bin" command
   CMINVOKECOMMANDINFO cmi;
   ::ZeroMemory(&cmi, sizeof(CMINVOKECOMMANDINFO));

   cmi.cbSize = sizeof(CMINVOKECOMMANDINFO);
   cmi.fMask = 0;
   cmi.hwnd = GetSafeHwnd();
   cmi.lpParameters = NULL;
   cmi.lpDirectory = NULL;
   cmi.nShow = SW_SHOWNORMAL;
   cmi.dwHotKey = 0;
   cmi.hIcon = NULL;
   cmi.lpVerb = MAKEINTRESOURCE(0x72);

   hr = pIContextMenu->InvokeCommand(&cmi);
   if (SUCCEEDED(hr))
   {
    bSuccess = TRUE;
   }
  }
 }
 ::CoUninitialize();
 AfxMessageBox((TRUE == bSuccess ? "SUCCESS" : "FAILURE"));
}

Tom

That worked!  Now I need to have it happen without asking the user (ie they have already confirmed in my program).

Thanks!

Don

Don,

Actually, I should also thank you. Thank you for not letting me slide by with a "you kinda do this and then you kinda do that" answer. Because you insisted on a real answer, I put in the extra effort necessary and learned something new in the process.

As I said, my "resolution" is not perfect, but when I get all the kinks worked out and wrap it with a C++ class, I'll send you the new version.

Tom

Thanks, Tom.  I appreciate the effort!

Don
Tom,

Were you going to put together this into a C++ class?  Also - any idea on how to turn off recycle bin emptying notification?

Thanks,

Don
Sorry. We're in deadline mode on our latest book (Visual C++ 6 Bible) and I haven't had any more time to devote to it. This weekend I will be finished with my last chapter and I planned on finally uploading a lot of my code to my web site. I'll post when its up (probably by Monday).

Tom

Thanks - if you would send an email to me directly (barefoot@pobox.com) I'd appreciate it (off topic for this).

Don
Sorry for butting in guys (like its two years ago since you all spoke - but does this code work on ALL versions of windows9? ??
Sorry for butting in guys (like its two years ago since you all spoke - but does this code work on ALL versions of windows9? ??
I think it did for me.  Let me check my code and get back to you.

don
Greatly appreciated if you can - I've managed to get the code to work in C with a little help from NickRepin - Many thanks for the response

DarrinE