Get Internal Drives Using Windows.Storage Namespace in UWP

和自甴很熟 提交于 2019-12-11 15:08:19

问题


Having spent some time reading up on the Windows.Storage classes and methods, I'm a bit shocked to find that there is no simple way to retrieve a list of the internal drives on a machine using UWP. I've found examples such as this: How to get logical drives names in Windows 10?, but this provides the removable drives only (Flash drives, DVD drive, etc).

I know I can allow the user to select a folder and that'll provide me with the handle to the selected drive, but it seems clunky as I want the user to be able to run my software and scan the internal disks on the PC without having to re-select the drives every time.

I've added the broadFileSystemAccess attribute to the manifest so have access to the disks, I just can't call a method to get the internal drives. As a workaround, I've written the following method.

public List<StorageFolder> GetInternalDrives()
{
    string driveLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int driveLettersLen = driveLetters.Length;
    string removableDriveLetters = "";
    string driveLetter;

    List<StorageFolder> drives = new List<StorageFolder>();
    StorageFolder removableDevices = KnownFolders.RemovableDevices;
    IReadOnlyList<StorageFolder> folders = Task.Run<IReadOnlyList<StorageFolder>>(async () => await removableDevices.GetFoldersAsync()).Result;

    foreach (StorageFolder removableDevice in folders)
    {
        if (string.IsNullOrEmpty(removableDevice.Path)) continue;
        driveLetter = removableDevice.Path.Substring(0, 1).ToUpper();
        if (driveLetters.IndexOf(driveLetter) > -1) removableDriveLetters += driveLetter;
    }

    for (int curDrive = 0; curDrive < driveLettersLen; curDrive++)
    {
        driveLetter = driveLetters.Substring(curDrive, 1);
        if (removableDriveLetters.IndexOf(driveLetter) > -1) continue;

        try
        {
            StorageFolder drive = Task.Run<StorageFolder>(async () => await StorageFolder.GetFolderFromPathAsync(driveLetter + ":")).Result;
            drives.Add(drive);
        }
        catch (System.AggregateException) { }

    }

    return drives;
}

And here's an example of GetInternalDrives being called:

List<StorageFolder> drives = GetInternalDrives();
panScanParams.Children.Clear();
foreach (StorageFolder drive in drives)
{
    CheckBox cb = new CheckBox();
    cb.Content = drive.DisplayName;
    cb.IsChecked = true;
    panScanParams.Children.Add(cb);
}

Whilst the code is only invoked once for an instance of the app, I'm not at all happy with the code. As it calls StorageFolder.GetFolderFromPathAsync for every letter of the alphabet, it crashes over 20 times on my machine. Writing code which you expect to fail and handling the exception just seems bad practice. But with the lack of a suitable alternative, I don't know what other options I have.

Has anyone tackled the same problem, and if so, what did you do to resolve it?


回答1:


Or you can try this code var driveLetters = DriveInfo.GetDrives().Select(x => x.RootDirectory.Root).ToList().OrderBy(x => x.Root.FullName).ToList(); to get drives instead of using StorageFolder method to exclude one by one. After that, traversing the resulting list and convert to StorageFolder. Below code I haven't removed removable drives.

var driveLetters = DriveInfo.GetDrives().Select(x => x.RootDirectory.Root).ToList().OrderBy(x => x.Root.FullName).ToList();
List<StorageFolder> drives = new List<StorageFolder>();
foreach (var driveInfo in driveLetters)
{
    String a = driveInfo.ToString();
    StorageFolder drive = Task.Run<StorageFolder>(async () => await StorageFolder.GetFolderFromPathAsync(a)).Result;
    drives.Add(drive);
}


来源:https://stackoverflow.com/questions/58493950/get-internal-drives-using-windows-storage-namespace-in-uwp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!