FileOpenPicker throws UnauthorizedAccessException
本文关键字:UnauthorizedAccessException throws FileOpenPicker | 更新日期: 2023-09-27 18:33:26
我目前正在开发一个示例Windows 8应用程序,该应用程序加载日志文件并将其处理以显示在DevExpress XtraGrid中。当我将所需的扩展名添加到文件类型筛选器时,代码会引发 UnauthorizedAccessException,即使我将文件扩展名添加到 appxmanifest 中也是如此:
private void OpenFile()
{
try
{
FileOpenPicker pickLog = new FileOpenPicker();
pickLog.CommitButtonText = "Logdatei öffnen";
pickLog.SuggestedStartLocation = PickerLocationId.ComputerFolder;
pickLog.ViewMode = PickerViewMode.List;
pickLog.FileTypeFilter.Add(".log"); //This is where the code jumps out
pickLog.FileTypeFilter.Add(".slg");
pickLog.PickSingleFileAsync().Completed += delegate
{
StorageFile logFile = pickLog.PickSingleFileAsync().GetResults();
Stream strLog = logFile.OpenStreamForReadAsync().Result;
vm.LoadCommand.Execute(strLog);
};
pickLog.PickSingleFileAsync();
}
catch (Exception ex) //Catches UnauthorizedAccessException
{
MessageDialog md = new MessageDialog(ex.Message, ex.GetType().ToString());
md.ShowAsync();
}
}
更糟糕的是,如果我注释掉 FileTypeFilter 行,代码会跳出我在那里添加的匿名方法:
private void OpenFile()
{
try
{
FileOpenPicker pickLog = new FileOpenPicker();
pickLog.CommitButtonText = "Logdatei öffnen";
pickLog.SuggestedStartLocation = PickerLocationId.ComputerFolder;
pickLog.ViewMode = PickerViewMode.List;
//pickLog.FileTypeFilter.Add(".log");
//pickLog.FileTypeFilter.Add(".slg");
pickLog.PickSingleFileAsync().Completed += delegate //This is where the code jumps out
{
StorageFile logFile = pickLog.PickSingleFileAsync().GetResults();
Stream strLog = logFile.OpenStreamForReadAsync().Result;
vm.LoadCommand.Execute(strLog);
};
pickLog.PickSingleFileAsync();
}
catch (Exception ex) //Catches COMException
{
MessageDialog md = new MessageDialog(ex.Message, ex.GetType().ToString());
md.ShowAsync();
}
}
我连续几天做了彻底的研究,没有工作结果(来源包括StackOverflow(,这就是为什么我在这里提出这个问题。我感谢这里提供的任何帮助:)
更新:
抛出 COMException 时,HRESULT 始终为 (0x80070005(,但内部 HRESULT(显示在"详细信息"窗口中的 HRESULT(通常为 -21474xxxxx,但是当我使用提升的右侧在 VS 中调试我的应用程序时,内部 HRESULT 为 -2147024891。
您似乎没有await
PickSingleFileAsync
调用。
你应该做这样的事情:
StorageFile file = await picker.PickSingleFileAsync();
从"选取"操作中获得StorageFile
后,可以针对它执行任何操作。
您必须停止执行,直到从选取器返回选择。基本上,这是通过上面的行为您处理的。
此外,我看到MessageDialog
的ShowAsync
也是一个不等待的异步调用。用法应该是:
var messageDialog = new MessageDialog(...);
await messageDialog.ShowAsync();
或更短 :
await new MessageDialog('','').ShowAsync();
Microsoft强制执行此准则,即对声明为异步的任何方法使用 Async
后缀,以便更清楚地了解如何使用它。我想你也应该使用它。
作为一种好的做法,如果要启动异步调用,则必须在某个时候等待它,否则可能会获得不可预测的结果,这在大多数情况下会导致应用程序崩溃。
此外,当您想显示同一类型的两个消息对话框时,您也会遇到这种类型的异常。您一次只能在屏幕上显示一个消息对话框,当第一个消息对话框已经显示时,第二个对话框将尝试一个将抛出UnauthorizedAccessException
的操作。
编辑
以下是您应该如何更改代码:
private async Task OpenFile()
{
try
{
FileOpenPicker pickLog = new FileOpenPicker();
pickLog.CommitButtonText = "Logdatei öffnen";
pickLog.SuggestedStartLocation = PickerLocationId.ComputerFolder;
pickLog.ViewMode = PickerViewMode.List;
pickLog.FileTypeFilter.Add(".log"); //This is where the code jumps out
pickLog.FileTypeFilter.Add(".slg");
StorageFile logFile = await pickLog.PickSingleFileAsync();
//operations on logFile are safe to be done here (open stream, loadCommand etc)
}
catch (Exception ex) //Catches UnauthorizedAccessException
{
MessageDialog md = new MessageDialog(ex.Message, ex.GetType().ToString());
md.ShowAsync();
}
}
无需为选取器的Completed
事件添加事件处理程序。在PickSingleFileAsync
调用完成后,只需在logFile
上运行代码即可。我无法提供完整的工作代码,因为我不知道您的逻辑。但无论如何,请确保您还await
OpenStreamForReadAsync
调用(MSDN 文档(。