我目前正在开发一个示例Windows 8应用程序,它可以加载一个日志文件并对其进行处理,以便在DevExpress XtraGrid中显示。当我向Filetype Filter添加所需的扩展时,代码抛出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)通常为-21474xxxx,但是当我在VS中调高我的应用程序时右上角,内部HRESULT是-2147024891。
答案 0 :(得分:1)
您似乎await
PickSingleFileAsync
来电{。}}。
你应该这样做:
StorageFile file = await picker.PickSingleFileAsync();
从Pick操作中获得StorageFile
后,您可以对其执行任何操作。
您必须停止执行,直到返回选择器中的选择。基本上,这是通过上面的行处理的。
此外,我发现MessageDialog
' s 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();
}
}
您不需要为Picker的Completed
事件添加事件处理程序。只需在logFile
调用完成后PickSingleFileAsync
上运行您的代码即可。我无法提供完整的工作代码,因为我不了解您的逻辑。但无论如何,请确保await
OpenStreamForReadAsync
来电{{1}}。{{1}}。