Jonathan Viju Mathai
Jonathan Viju Mathai

Reputation: 437

How to Eject a Flash drive in Batch or Vbs

I'm trying to eject my flash drive when i type eject into a command prompt, i have a shell of a code, but i don't have the actual code to eject it.

UNLOCK

@echo off
echo '
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%p

if %password%==Eject goto EJECT

:EJECT

^if EXIST "D:\Some file in the Flash drive" goto D-DRIVE

:D-DRIVE

^code that ejects the D drive

after that bit i need the eject code

Upvotes: 1

Views: 4036

Answers (1)

rojo
rojo

Reputation: 24466

I was about to comment that same thing that mojo did above at about the same time. However, after testing, it seems that scripting diskpart to dismount my own removable drives prevents them from automatically re-acquiring a drive letter the next time they're plugged in. I had to go to Disk Management and re-assign a drive letter when re-plugging. I'm sure that's not what you want. Scripting a dismount with Win32_Volume like this guy did had the same unfortunate side effect.

Playing with hotplug.dll like this guy did wasn't much help either, with Windows reporting that the type of drive wasn't a removable drive.

No, the most reliable, least side-effect-y method that doesn't require 3rd party utilities is to invoke the "Eject" verb from a "My Computer"-ish context. Here's a solution involving a batch / JScript hybrid script:

@if (@a==@b) @end   /* JScript ignores this multiline comment

:: dismount.bat
:: safely dismounts all removable drives

@echo off
setlocal

cscript /nologo /e:JScript "%~f0"

goto :EOF

:: end batch portion / begin JScript portion */

// DriveType=1 means removable drive for a WScript FSO object.
// See http://msdn.microsoft.com/en-us/library/ys4ctaz0%28v=vs.84%29.aspx

// NameSpace(17) = ssfDRIVES, or My Computer.
// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb774096%28v=vs.85%29.aspx

var oSH = new ActiveXObject('Shell.Application'),
FSO = new ActiveXObject('Scripting.FileSystemObject'),
removableDriveType = 1,
ssfDRIVES = 17,
drives = new Enumerator(FSO.Drives);

while (!drives.atEnd()) {
    var x = drives.item();
    if (x.DriveType == removableDriveType) {
        oSH.NameSpace(ssfDRIVES).ParseName(x.DriveLetter + ':').InvokeVerb('Eject');
        while (x.IsReady)
            WSH.Sleep(50);
    }
    drives.moveNext();
}

Also, you can invoke the "Eject" verb from the same namespace using PowerShell in a similar way, but you'll still need to Start-Sleep to prevent the ps thread from exiting before the drive has been ejected. I leave that as an exercise for the O.P. if he prefers PowerShell over WScript.


Edit: If you want to define a specific drive to dismount in your batch script, do it like this:

@if (@a==@b) @end   /*

@echo off
setlocal

set "drive=F:"

cscript /nologo /e:JScript "%~f0" "%drive%"

goto :EOF

::  */

var oSH = new ActiveXObject('Shell.Application'),
    FSO = new ActiveXObject('Scripting.FileSystemObject'),
    drive = WSH.Arguments(0);

oSH.NameSpace(17).ParseName(drive).InvokeVerb('Eject');
while (FSO.GetDrive(drive).IsReady) WSH.Sleep(50);

Upvotes: 2

Related Questions