- NSIS Discussion
- Safe way to close Windows Explorer? (Need to Safely Remove Hardware)
Archive: Safe way to close Windows Explorer? (Need to Safely Remove Hardware)
thivnor
1st March 2010 21:47 UTC
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?
Anders
1st March 2010 21:56 UTC
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
MSG
2nd March 2010 06:22 UTC
Safe removal shouldn't fail just because you have an explorer window open... I think your problem lies elsewhere.
Wizou
2nd March 2010 10:26 UTC
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
jpderuiter
2nd March 2010 15:47 UTC
Well, I guess the safe removal isn't possible because your installer is still running from that USB drive...
Wizou
2nd March 2010 16:08 UTC
@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.
thivnor
2nd March 2010 17:15 UTC
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!
{_trueparuex^}
3rd March 2010 10:11 UTC
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.
thivnor
3rd March 2010 15:51 UTC
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.