Jump to content

Ejecting USB Drive


Go to solution Solved by BrewManNH,

Recommended Posts

I'm working on a script that will eject a usb flash drive.  I did a search on google and the forums and I found a script that people seem to be using for this purpose.  However when I try to us it, the script runs but it doesn't eject the usb flash drive

Here is the script exactly as I am trying to test it

#include <Process.au3>

$DriveLabel = "BACKUP" ; your drive label here

$aDrives = DriveGetDrive("all") ; USB external hard drives report as "Fixed", not "Removable", so use "All" to cover both kinds

If NOT @error Then
    For $i = 1 to $aDrives[0]
        If DriveGetLabel($aDrives[$i]) = $DriveLabel Then
            Local $dstatus = DriveStatus($aDrives[$i])
            MsgBox(0, "1", "Found Drive, it's status is: " & $dstatus)
            If DriveStatus($aDrives[$i]) = "READY" Then
                _RunDos("sync.exe -r "&$aDrives[$i]) ; Flush drive cache
                Sleep(2000)
                EjectDrive($aDrives[$i] & "\")
            EndIf
            Exit
        EndIf
    Next
EndIf

Exit

Func EjectDrive($dLetter) ; From VB script, Authors XoLoX and ChrisL
Local CONST $SSF_DRIVES = 17
Local $oShell, $oNameSpace, $oDrive, $strDrive
$strDrive = $dLetter
$strName=DriveGetLabel($strDrive) & "(" & $strDrive & ")"
$oShell = ObjCreate("Shell.Application")
$oNamespace = $oShell.NameSpace($SSF_DRIVES)
$oDrive = $oNamespace.ParseName($strDrive)
$oDrive.InvokeVerb ("E&ject")
MsgBox(0, "2", "We're here in the function")
If DriveGetLabel($aDrives[$i]) <> $DriveLabel Or DriveGetLabel($aDrives[$i]) = "Removeable Disk" Then
    MsgBox(0, "3", "We're here in the if statement")
    TrayTip("USB Drive "&$strName&" ejected", "You can now remove the device safely.", 5, 1)
    MsgBox(0,"", $strName & " drive ejected. You can now remove the device safely.",5)
EndIf
Endfunc

It's pretty much the exact script found in numerous posts here on the fourm.  I only modified the drive label and added some message boxes to see where in the script the problem was.

the script runs fine up until the "if" statement in function EjectDrive().  If I understand the script, that if statement determines if the drive has actually been ejected.  If it has then it send the message that it's save to remove the device.

When I run the script is does not actually eject the drive so I'm sure that's why the code in the if statement isn't executed.

The Question: What do I need to do to get the script to actually eject the flash drive.

P.S. I'm using windows 7 32-bit if it makes a difference.

Link to comment
Share on other sites

Try this modification, there were numerous things wrong with what you posted.
 

#include <Process.au3>

$DriveLabel = "usbdrive" ; your drive label here

$aDrives = DriveGetDrive("all") ; USB external hard drives report as "Fixed", not "Removable", so use "All" to cover both kinds

If Not @error Then
    For $i = 1 To $aDrives[0]
        If DriveGetLabel($aDrives[$i]) = $DriveLabel Then
            Local $dstatus = DriveStatus($aDrives[$i])
            MsgBox(0, "1", "Found Drive, it's status is: " & $dstatus)
            If DriveStatus($aDrives[$i]) = "READY" Then
                _RunDos("sync.exe -r " & $aDrives[$i]) ; Flush drive cache
                Sleep(2000)
                EjectDrive($aDrives[$i] & "\")
            EndIf
            Exit
        EndIf
    Next
EndIf

Exit

Func EjectDrive($dLetter) ; From VB script, Authors XoLoX and ChrisL
    Local Const $SSF_DRIVES = 17
    Local $oShell, $oNameSpace, $oDrive, $strDrive
    $strDrive = $dLetter
    $strName = DriveGetLabel($strDrive) & "(" & $strDrive & ")"
    $oShell = ObjCreate("Shell.Application")
    $oNameSpace = $oShell.NameSpace($SSF_DRIVES)
    $oDrive = $oNameSpace.ParseName($strDrive)
    $oDrive.InvokeVerb("Eject")
    MsgBox(0, "2", "We're here in the function")
    TrayTip("USB Drive " & $strName & " ejected", "You can now remove the device safely.", 5, 1)
    MsgBox(0, "", $strName & " drive ejected. You can now remove the device safely.", 5)
EndFunc   ;==>EjectDrive

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Thanks for the quick reply.  I looked over the modifications that you made.  I see in the script that I posted, line 32 has an "&" in the middle of the work "Eject".  I don't know why it was there but removing it allowed the script to work in windows 7.  I then tested the script in window xp... and it isn't ejecting the drive :( .  Does Windows XP require some other method of ejecting a usb flash drive?

Link to comment
Share on other sites

  • Solution

Try putting the & back in and testing it on XP. I ran this on Windows 7 and it wouldn't work with the & but works fine without it. Although all the examples I've found doing a search uses the & in the eject command string, it won't work on 7 with it.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

You are correct.

I just did as you suggested and put the "&" back in and it works in Windows XP.  Without the "&" it works in Windows 7.

So, I 'll need to put in some sort of a check for the OS version so script know's which command to execute.  Once I get that lined out and tested I'll post the final version here for others that may have the same problem.

Thanks again BrewManNH for the help.

Link to comment
Share on other sites

Look at @OSVersion to determine which OS your script is running on and something like this would suffice for the change needed.

Local $sEject = "E&ject")
If @OSVersion <> "WIN_XP" Then $sEject = "Eject"
; then change the following line to use the above variable.
$oDrive.InvokeVerb($sEject)

That should work, but untested.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

I tried what you posted and the script wasn't sending the message that it was ok to remove the drive.  So, i changed up the if statement where it checks the os version and still had the same problem.  But then i added a sleep statement and it worked.  Appearantly it takes the OS a second to register the drive as ejected.

Here is the code that I ended up with:

#include <Process.au3>

$DriveLabel = "SOMELABEL" ; your drive label here

$aDrives = DriveGetDrive("all") ; USB external hard drives report as "Fixed", not "Removable", so use "All" to cover both kinds

If NOT @error Then
    For $i = 1 to $aDrives[0]
        If DriveGetLabel($aDrives[$i]) = $DriveLabel Then
            Local $dstatus = DriveStatus($aDrives[$i])
            If DriveStatus($aDrives[$i]) = "READY" Then
                _RunDos("sync.exe -r "&$aDrives[$i]) ; Flush drive cache
                Sleep(2000)
                EjectDrive($aDrives[$i] & "\")
            EndIf
            Exit
        EndIf
    Next
EndIf

Exit

Func EjectDrive($dLetter) ; From VB script, Authors XoLoX and ChrisL
Local CONST $SSF_DRIVES = 17
Local $oShell, $oNameSpace, $oDrive, $strDrive
$strDrive = $dLetter
$strName=DriveGetLabel($strDrive) & "(" & $strDrive & ")"
$oShell = ObjCreate("Shell.Application")
$oNamespace = $oShell.NameSpace($SSF_DRIVES)
$oDrive = $oNamespace.ParseName($strDrive)

If @OSVersion = "WIN_XP" Then
    $oDrive.InvokeVerb ("E&ject")
Else
    $oDrive.InvokeVerb ("Eject")
EndIf
Sleep(2000)

If DriveGetLabel($aDrives[$i]) <> $DriveLabel Or DriveGetLabel($aDrives[$i]) = "Removeable Disk" Then
    TrayTip("USB Drive "&$strName&" ejected", "You can now remove the device safely.", 5, 1)
    MsgBox(0,"", $strName & " drive ejected. You can now remove the device safely.",5)
EndIf
Endfunc

I tested this on Win_XP SP3 32-bit, Win Vista 64-bit and Win 7 32-bit.

The shorter version that you posted would have probably done the trick if I had thought to put the sleep statement in there.

Link to comment
Share on other sites

Func EjectDrive($strDrive) ; From VB script, Authors XoLoX and ChrisL
    Local Const $SSF_DRIVES = 17
    Local $oShell, $oNameSpace, $oDrive
    Local $strName = DriveGetLabel($strDrive) & "(" & $strDrive & ")"
    $oShell = ObjCreate("Shell.Application")
    $oNameSpace = $oShell.NameSpace($SSF_DRIVES)
    $oDrive = $oNameSpace.ParseName($strDrive)
    Local $sEject = "E&ject"
    If @OSVersion <> "WIN_XP" Then $sEject = "Eject"
    $oDrive.InvokeVerb($sEject)
    MsgBox(0, "2", "We're here in the function")
    TrayTip("USB Drive " & $strName & " ejected", "You can now remove the device safely.", 5, 1)
    MsgBox(0, "", $strName & " drive ejected. You can now remove the device safely.", 5)
EndFunc   ;==>EjectDrive
 

I tried it and didn't need a sleep in there, there shouldn't be any reason to use a sleep for this change.

 

You also don't need the If statement in the original function. You're sending it (the function) a drive letter that your script has already determined is the correct drive letter by checking the drive label. There's no need to check to see if it's the right one twice. You'll notice in the rewrite I did, it's using the $strDrive parameter in the function header instead of any global variables. 

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

 

There are a few things I feel the need to point out here.

1. Sync.exe has an eject parameter so the drive can be ejected after it's flushed instead of using another function.

I wasn't focusing on the whole sync.exe part, as it's not even on Windows 7 and was irrelevant to the problem. I don't know what Sync.exe does or what parameters it uses.

2. _RunDos and Sleep should be replaced with RunWait. This is irrelevant if sync.exe is used to eject the drive.

_RunDos and RunWait are the same thing, it's just that RunDos is a wrapper for RunWait to make it easier to use for beginners.

3. These methods are the same as right clicking the drive and selecting "Eject" but neither method is the same as using the Safely Remove Hardware dialog. I'm unsure what implications this has if any.

On Windows 7, ejecting the drive with right clicking the drive and selecting Eject and right clicking the USB icon in the system tray and selecting Eject work similarly, except that you still have a drive letter assigned for the drive "ejected" after using Eject on the drive where you don't have that on the other method. You still get the message that it's safe to remove the drive after running this script.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Sync basically flushes all file data to the disk, it's a SysInternals application.

I have some previous knowledge of creating such a tool.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...