Try Win32::DriveInfo. The DrivesInUse routine returns an array of all drive-letters in use.
Update: I ran this little test on my system
use strict;
use warnings;
use Win32::DriveInfo;
my @drives = Win32::DriveInfo::DrivesInUse();
print join( "\n", @drives );
Output:
A
C
D
| [reply] [d/l] [select] |
use Win32::OLE qw( in );
my $wmi_service = Win32::OLE->GetObject("winmgmts:{impersonationLevel=
+impersonate}!\\\\.\\root\\cimv2")
or die("Unable to connect to WMI: $!\n");
# DriveType 3 = local hard disk
my $disk_col = $wmi_service->ExecQuery("
SELECT DeviceID
FROM Win32_LogicalDisk
WHERE DriveType = 3
");
my @drives = map { $_->DeviceID } in $disk_col;
local $, = ", ";
local $\ = "\n";
print @drives;
On my computer, the above prints C:, D:, E:.
If I remove the WHERE clause, it prints A:, B:, C:, D:, E:, F:, G:, H: (Floppy drives, hard drives, optical drives, USB drives, network drives, virtual drives, etc.)
| [reply] [d/l] [select] |
| [reply] |
sub drives {
my @drives = ();
eval{require Win32API::File;};
return map {"$_:\\"} ('C' .. 'Z') if $@;
my @r = Win32API::File::getLogicalDrives();
return unless @r > 0;
for (@r) {
my $t = Win32API::File::GetDriveType($_);
push @drives, $_ if ($t == 3 or $t == 4);
}
return @drives > 0 ? @drives : undef;
}
| [reply] [d/l] |