Archive: Safe way to close Windows Explorer? (Need to Safely Remove Hardware)


Safe way to close Windows Explorer? (Need to Safely Remove Hardware)
I have an application which runs from a USB drive. I guess it would be considered a Portable App.

I want to "Safely Remove" the USB drive when the application is closed. However, since the program is launched from Windows Explorer, the "Safely Remove" action always fails, because Windows Explorer is open and looking at the folder from which the software was launched.

A smart user could close Windows Explorer after launching my program. But my users aren't that smart. I want this happen automatically.

My root objective is simply to "Safely Remove"the USB drive. It seem like I need to either close Windows Explorer, or get it to "look" at a different folder.

I'm tried closing Windows Explorer, using things like KillProcDLL::KillProc and SendMessage ... ${WM_CLOSE}. Those actions are really drastic however, and either leave Windows Explorer is some half-dead state, or worse. At one point Windows was asking if I wanted to shut down! Ok I'm over my head here :)

Is there a safe way to close Windows Explorer?

Or to have it "look elsewhere" so I can eject the USB drive?


create a windows scripting host script (This can also be done with COM called by the system plugin, but that is more code than I want to type in this little box)

JScript:


var ShA=new ActiveXObject("Shell.Application");
var sw=ShA.Windows();//list of explorer windows
for(var i=0;i<sw.Count; ++i) WScript.Echo(sw.Item(i).LocationURL); //sw.Item(i).HWND for handle, sw.Item(i).Refresh(), sw.Item(i).Quit() etc


See http://msdn.microsoft.com/en-us/libr...74(VS.85).aspx for more

Safe removal shouldn't fail just because you have an explorer window open... I think your problem lies elsewhere.


take a look at the SHChangeNotify shell function, it has several "removal" options which Explorer handles by closing the adequate windows if any were open on the given drive


Well, I guess the safe removal isn't possible because your installer is still running from that USB drive...


@jpderuiter: good point!
A workaround could be to extract & run a small program in %TEMP% just before exiting the installer (make sure the working directory is also %TEMP%) and have it close Explorer windows (with SHChangeNotify) and remove the USB device.


Sorry I should have provided a bit more detail.

To eject the drive, I use a "RemoveDrive.exe" utility, from http://www.uwe-sieber.de/drivetools_e.html. This utility is pretty smart. It places a copy of itself in the temp folder and then runs the copy in temp.

Also, I'm pretty confident the problem really is Windows Explorer. It seems odd that Windows Explorer would "lock" the drive ... just my "looking" at the drive. But that is what my testing has revealed.

I'm going to look into SHChangeNotify and see how to use it & if it works. I will have my .exe run from %TEMP%.


THANK YOU for all the suggestions!


Originally posted by MSG
Safe removal shouldn't fail just because you have an explorer window open... I think your problem lies elsewhere.
True in Windows XP and 2000, but in Vista and probably in Windows 7, open explorer windows on the drive will block the safe removal.

Yeah ... the removable behavior has changed in Vista. I just re-tested this, to ensure I'm not crazy. I did my testing with my software closed ... I was just testing various USB ejection techniques and tools, with a single Windows Explorer window "looking" at the USB drive. So I'm very confident that this isn't related to a program still running on the USB drive. It is something new in Vista.

I looked into SHChangeNotify but don't have the skills to put together a solution. I code a lot of languages but C++ isn't one of them, and I'm really not up on the Windows API. That's why I use NSIS anytime I need something Windowsy to happen ;)

I tested different USB ejection tools and found that EjectUSB com will close Windows Explorer. ("EjectUSB – Safe USB Ejection Tool" from pendriveapps dot com). It is smart about only closing the affected Windows Explorer instances.

It isn't as fast as the RemoveDrive tool which I had been using. (Part of "Drive Tools for Windows" from uwe-sieber dot de). But it works, and it provides a return code so I can report success or failure to the user.

I will probably end up embedding EjectUSB instead of RemoveDrive.