使用UWP中的Windows.Storage命名空间获取内部驱动器

使用UWP中的Windows.Storage命名空间获取内部驱动器,uwp,known-folders,Uwp,Known Folders,在花了一些时间阅读Windows.Storage类和方法之后,我有点震惊地发现,没有简单的方法可以使用UWP检索机器上的内部驱动器列表。我发现了这样的例子:,但它只提供可移动驱动器(闪存驱动器、DVD驱动器等) 我知道我可以允许用户选择一个文件夹,这将为我提供所选驱动器的句柄,但这似乎很笨拙,因为我希望用户能够运行我的软件并扫描电脑上的内部磁盘,而无需每次重新选择驱动器 我已将broadFileSystemAccess属性添加到清单中,以便能够访问磁盘,但我无法调用方法来获取内部驱动器。作为一种

在花了一些时间阅读Windows.Storage类和方法之后,我有点震惊地发现,没有简单的方法可以使用UWP检索机器上的内部驱动器列表。我发现了这样的例子:,但它只提供可移动驱动器(闪存驱动器、DVD驱动器等)

我知道我可以允许用户选择一个文件夹,这将为我提供所选驱动器的句柄,但这似乎很笨拙,因为我希望用户能够运行我的软件并扫描电脑上的内部磁盘,而无需每次重新选择驱动器

我已将broadFileSystemAccess属性添加到清单中,以便能够访问磁盘,但我无法调用方法来获取内部驱动器。作为一种变通方法,我编写了以下方法

public List getInternalDrive()
{
string driveLetters=“abcdefghijklmnopqrstuvxyz”;
int driveletteslen=driveLetters.Length;
字符串removableDriveLetters=“”;
字符串驱动字母;
列表驱动器=新列表();
StorageFolder removableDevices=KnownFolders.removableDevices;
IReadOnlyList folders=Task.Run(async()=>await removableDevices.GetFoldersAsync()).Result;
foreach(文件夹中的StorageFolder removableDevice)
{
如果(string.IsNullOrEmpty(removableDevice.Path))继续;
driveLetter=removableDevice.Path.Substring(0,1.ToUpper();
if(driveLetters.IndexOf(driveLetter)>-1)removableDriveLetters+=driveLetter;
}
对于(int curDrive=0;curDrive-1)继续;
尝试
{
StorageFolder drive=Task.Run(async()=>wait-StorageFolder.GetFolderFromPathAsync(driveLetter+“:”)。结果;
驱动器。添加(驱动器);
}
catch(System.aggregateeexception){}
}
返回驱动器;
}
下面是一个调用GetInternalDrive的示例:

List drives=GetInternalDrives();
panScanParams.Children.Clear();
foreach(驱动器中的StorageFolder驱动器)
{
复选框cb=新复选框();
cb.Content=drive.DisplayName;
cb.IsChecked=true;
panScanParams.Children.Add(cb);
}
虽然对于应用程序的一个实例,代码只被调用一次,但我对代码一点也不满意。当它为字母表中的每个字母调用StorageFolder.GetFolderFromPathAsync时,它在我的机器上崩溃了20多次。编写预期会失败的代码并处理异常似乎是一种糟糕的做法。但由于缺乏合适的选择,我不知道还有什么其他选择


有人解决过同样的问题吗?如果有,你是怎么解决的?

或者你可以试试下面的代码
var driveLetters=DriveInfo.GetDrives().Select(x=>x.RootDirectory.Root).ToList().OrderBy(x=>x.Root.FullName).ToList()
获取驱动器,而不是使用StorageFolder方法逐个排除。之后,遍历生成的列表并转换为StorageFolder。下面的代码我没有删除可移动驱动器

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);
}
var driveLetters=DriveInfo.GetDrives().Select(x=>x.RootDirectory.Root).ToList().OrderBy(x=>x.Root.FullName).ToList();
列表驱动器=新列表();
foreach(以driveLetters表示的var driveInfo)
{
字符串a=driveInfo.ToString();
StorageFolder drive=Task.Run(async()=>wait-StorageFolder.GetFolderFromPathAsync(a)).Result;
驱动器。添加(驱动器);
}

或者您可以尝试以下代码
var driveLetters=DriveInfo.GetDrives().Select(x=>x.RootDirectory.Root).ToList().OrderBy(x=>x.Root.FullName).ToList()
获取驱动器,而不是使用StorageFolder方法逐个排除。之后,遍历生成的列表并转换为StorageFolder。下面的代码我没有删除可移动驱动器

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);
}
var driveLetters=DriveInfo.GetDrives().Select(x=>x.RootDirectory.Root).ToList().OrderBy(x=>x.Root.FullName).ToList();
列表驱动器=新列表();
foreach(以driveLetters表示的var driveInfo)
{
字符串a=driveInfo.ToString();
StorageFolder drive=Task.Run(async()=>wait-StorageFolder.GetFolderFromPathAsync(a)).Result;
驱动器。添加(驱动器);
}

在UWP中,可能出于安全原因,没有直接列出所有驱动程序的方法。但当我使用您的代码进行测试时,它运行得很好,所以当您为每个字母调用StorageFolder.GetFolderFromPathAsync()时,它抛出了什么异常?以及您是否在“设置”>“隐私”>“文件系统”中配置了访问权限以允许应用程序访问文件系统?对于不存在的驱动器号调用StorageFolder.GetFolderFromPathAsync()时,将引发system.AggregateException。Microsoft文档()未将AggregateException列为可能引发的异常。我本以为会出现FileNotFoundException异常,但这很可能是在我使用Task.Run执行代码时发生的;我可以很容易地将我的方法更改为async来测试theory.PS。我确实需要将我的应用程序添加到允许在设置/隐私中访问文件系统的列表中。我已经了解到有一种方法可以在首次启动应用程序时使用设置/隐私窗口提示用户。是的,当您将Task.Run与GetFolderFromPathAsync()结合使用时,它将触发多个异常,因此会引发AggregateException。现在,如果这段代码能够很好地实现您想要的效果,我已经调整了方法,使其与调用代码异步工作,以使用Task.Run更新UI。奇怪的是,现在引发的异常是一个普通的系统。异常消息“Error HRESULT E_FAIL已从对COM组件的调用中返回”。在UWP中,可能出于安全原因,没有方法直接列出所有驱动程序。但当我使用您的代码进行测试时,它运行良好,所以当您为每个字母调用StorageFolder.GetFolderFromPathAsync()时,它会引发什么异常