如何区分不同的"类型" UWP应用程序中的System.UnauthorizedAccessException?

时间:2017-01-31 16:50:59

标签: c# exception visual-studio-2015 uwp

此代码段尝试读取UWP应用允许位置之外的文件:

StorageFile sf2 = await StorageFile.GetFileFromPathAsync(Path.Combine("C:\\Temp", "spam.dat"));

抛出System.UnauthorizedAccessException,它被Visual Studio 2015调试器拦截并显示在一个漂亮的弹出窗口中:

WinRT exception dialog

整个文字如下:

类型' System.UnauthorizedAccessException'的例外情况发生在mscorlib.ni.dll但未在用户代码中处理

WinRT信息:无法访问指定的文件或文件夹(C:\ Temp \ spam.dat)。该项目不在应用程序可以访问的位置(包括应用程序数据文件夹,可通过功能访问的文件夹以及StorageApplicationPermissions列表中的持久项目)。验证文件未标记系统或隐藏文件属性。

类型' System.UnauthorizedAccessException'的例外情况发生在mscorlib.ni.dll但未在用户代码中处理

现在是另一个代码片段(此代码尝试读取已经打开的文件):

StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(ApplicationData.Current.LocalFolder.Path);
StorageFile file = await folder.CreateFileAsync("spam.dat", CreationCollisionOption.ReplaceExisting);
Stream fs = await file.OpenStreamForWriteAsync();
StorageFile sf2 = await StorageFile.GetFileFromPathAsync(Path.Combine(ApplicationData.Current.LocalFolder.Path, "spam.dat"));
await sf2.OpenStreamForReadAsync();

调试器中的异常屏幕看起来完全不同:

Normal exception dialog

其他信息:访问被拒绝。 (HRESULT异常:0x80070005(E_ACCESSDENIED))

我不明白调试器对这些异常的看法如何不同。在我的代码中,我需要了解获取UnauthorizedAccessException的原因 - 如果是因为文件被锁定以供阅读,因为它被另一个编写者占用(我可以稍后再试)或者由于其他原因,例如它在LocalFolder之外(并且它不值得重试)。我实际上正在开发一个将由UWP应用程序的开发人员使用的库,因此我不知道将给出哪个文件/文件路径,并且不能对权限,目录结构等做任何假设。我只是得到输入路径,如果发生任何事情,只能使用异常处理来理解原因。

因此,Visual Studio调试器以某种方式看到了差异,但我不知道如何以编程方式执行此操作。在两种情况下,InnerException都为null,HResult也是相同的(0x80070005)。

2 个答案:

答案 0 :(得分:1)

如果您要将.NET库移植到UWP,可能它根本不依赖StorageFile(在实现或公共接口中),所以我会继续使用.NET类型,它们有明显的错误(未经授权的访问与IO):

try
{
  var f = File.OpenRead(@"d:\temp\foo.txt");
}
catch (UnauthorizedAccessException ex)
{
  Debug.WriteLine(ex.Message);
}

try
{
  var localPath = ApplicationData.Current.LocalFolder.Path;
  var filename = Path.Combine(localPath, "foo.txt");
  var f1 = File.OpenWrite(filename);
  var f2 = File.OpenRead(filename);
}
catch (IOException ex)
{
  Debug.WriteLine(ex.Message);
}

如果我运行您的示例代码,我不会使用StorageFile获取写/读示例的任何异常(尽管我正在运行Windows 10 Creator更新的Insider Builds)。如果我尝试两次打开相同的文件进行书写,我会得到一个例外,但是投影为IOException

try
{
  var f = await StorageFile.GetFileFromPathAsync(@"d:\temp\foo.txt");
}
catch (UnauthorizedAccessException ex)
{
  Debug.WriteLine(ex.Message);
}

try
{
  var localFolder = ApplicationData.Current.LocalFolder;
  var f1 = await localFolder.CreateFileAsync("foo.txt", CreationCollisionOption.ReplaceExisting);
  var f2 = await localFolder.GetFileAsync("foo.txt");
  var s1 = await f1.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.AllowOnlyReaders);
  var s2 = await f2.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.AllowOnlyReaders);
}
catch (IOException ex)
{
  Debug.WriteLine(ex.Message);
}

答案 1 :(得分:0)

亚历,

对于第二个,您正在使用IO流而不处理您尝试在同一文件上创建另一个流的上一个流。因此,它阻止您说未经授权的访问。我已经介绍了刷新流并处理流然后代码正在为我工​​作。以下是修改后的代码:

StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(ApplicationData.Current.LocalFolder.Path);
        StorageFile file = await folder.CreateFileAsync("spam.dat", CreationCollisionOption.ReplaceExisting);
        Stream fs = await file.OpenStreamForWriteAsync();
        fs.Flush();
        fs.Dispose();
        StorageFile sf2 = await StorageFile.GetFileFromPathAsync(Path.Combine(ApplicationData.Current.LocalFolder.Path, "spam.dat"));
        var x = await sf2.OpenStreamForReadAsync();