Does anyone know of a method to list the physical disks on Windows using Flutter?

I've done a bunch of research but can't find anything. Only the path_provider, but that only provides access to the temp locations.

I suspect this isn't possible... 😢


Solution 1: julemand101

I don't think there are any method in the SDK which provides such a feature. But you can call another executable and parse the result.

In Windows you can get the list of available drives through:

C:\>wmic logicaldisk get caption
Caption
C:
E:
F:
G:
Z:

So we can create the following in Dart:

import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  print(await getDrivesOnWindows()); // (C:, E:, F:, G:, Z:)
}

Future<Iterable<String>> getDrivesOnWindows() async => LineSplitter.split(
        (await Process.run('wmic', ['logicaldisk', 'get', 'caption'],
                stdoutEncoding: const SystemEncoding()))
            .stdout as String)
    .map((string) => string.trim())
    .where((string) => string.isNotEmpty)
    .skip(1);

A more complicated example showing how to get multiple values out for each drive. The freeSpace is nullable since unconnected network drives (or empty CD/DVD drives) returns no value when asked for free disk space:

import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  (await WindowsDrive.getDrives()).forEach(print);
  // DriveLetter: C:, FreeSpace: 20392869888
  // DriveLetter: E:, FreeSpace: null
  // DriveLetter: F:, FreeSpace: 69761130496
  // DriveLetter: G:, FreeSpace: 85562028032
  // DriveLetter: Z:, FreeSpace: null
}

class WindowsDrive {
  final String driveLetter;
  final int? freeSpace;

  const WindowsDrive(this.driveLetter, this.freeSpace);

  // Node,Caption,FreeSpace
  factory WindowsDrive.parse(String line) {
    final segments = line.split(',');
    return WindowsDrive(segments[1], int.tryParse(segments[2]));
  }

  @override
  String toString() => 'DriveLetter: $driveLetter, FreeSpace: $freeSpace';

  static Future<Iterable<WindowsDrive>> getDrives() async =>
      LineSplitter.split((await Process.run(
                  'wmic',
                  [
                    'logicaldisk',
                    'get',
                    'caption',
                    ',',
                    'freespace',
                    '/format:csv'
                  ],
                  stdoutEncoding: const SystemEncoding()))
              .stdout as String)
          .map((string) => string.trim())
          .where((string) => string.isNotEmpty)
          .skip(1)
          .map((e) => WindowsDrive.parse(e));
}