2017-01-31 12 views
0

このコードスニペットは、UWPのアプリケーションに許可された場所の外にファイルを読み取ろうとします:UWPアプリケーションでSystem.UnauthorizedAccessExceptionの異なる "タイプ"を区別する方法はありますか?

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

は、Visual Studio 2015のデバッガでインターセプトされ、素敵なポップアップに表示されSystem.UnauthorizedAccessExceptionをスロー:

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)と同じです。

+0

あなたのライブラリーは、他の開発者によって使用されようとしているどのように正確に?それは何をするつもりですか?あなたにとって最良のことは、コードの消費者が状況をどのように処理したいかを決定できるように例外を処理しないことです。 –

+0

ライブラリは、複数のスレッドやアプリケーションインスタンスが同じ共有ファイルを同時に読み書きできる状況に対処することが期待されています。振る舞いは既に設定されており、変更することはできません。ライブラリはすでに他の.NETプラットフォームでこのように動作しています。私はUWPポートを作成しています。 – Alex

+0

そして私はなぜVisual Studioデバッガがこれらの例外を異なるように表示するのか不思議です。どういう違いがありますか? – Alex

答えて

0

アレックス、あなたが同じファイルに別のストリームを作成しようとしている以前のストリームを設けることなく、IOストリームで作業している1秒間

。したがって、あなたは不正アクセスを言うのを防ぎます。ストリームをフラッシュしてストリームを破棄し、コードが私のために働いています。

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(); 
+0

あなたは全体のポイントを理解していませんでした。私のコードは、この例外を生成するために特別に作られています。私は例外処理について説明しています。この例外を発生させる必要があります。 – Alex

+0

ああ申し訳ありません。あなたはすでにそれについて言及しています。それは私の悪かったです。私はあなたが2番目のタイプのコードでもそのような例外を受けていると思っていました.. –

1

あなたがUWPに.NETライブラリを移植している場合は、おそらくそれがすべてでStorageFileに依存関係がない(どちらかの実装やパブリックインターフェイスで)ので、私は.NETを使用し続けることになります。以下は、変更されたコードですタイプには、個別のエラーがあります(Unauthorized Access vs.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); 
} 

場合、私は)インサイダーは、Windows 10作者のアップデートのビルド実行していますが、私は(StorageFileを使用した例を読み取り/書き込みのための例外を得ることはありません。私は書き込みのために二度同じファイルを開こうとする場合、私は例外を得ることができますが、それはまた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); 
} 
+0

それは面白いです。私の質問に直接答えることはできませんが、ファイルアクセスの競合はUnauthorizedAccessExceptionだけでなくIOExceptionでも発生する可能性があります。この例では元の非UWP libが実際にIOExceptionを処理していましたが、移行中にこの条件が発生しないことがわかりました(私のケースではUnauthorizedAccessExceptionが発生しました)。しかし、あなたのケースは再びIOExceptionを表示します。私は両方の状況下で発生しているようです。 – Alex

+0

サンプルコードを直接コピーしましたが、共有違反によりエラーは発生しませんでした。これは、実行しているWindowsの特定のビルドに依存するものかもしれません(私たちは最近規則を緩和したかもしれないと思います)。あなたは 'HResult'プロパティをチェックしてそれが違うかどうか調べることができますか? –

+0

元の投稿から:InnerExceptionはどちらの場合もnullです.HResultは同じ(0x80070005)です。 – Alex

関連する問題