0

私は現在、ログファイルをロードし、DevExpress XtraGrid に表示されるように処理するサンプル Windows 8 アプリを開発しています。必要な拡張機能を Filetype フィルターに追加すると、ファイル拡張機能を appxmanifest に追加したにもかかわらず、コードは UnauthorizedAccessException をスローします。

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 です.

4

1 に答える 1

1

awaitあなたは電話に出ていないようですPickSingleFileAsync

あなたはこのようなことをしているはずです:

StorageFile file = await picker.PickSingleFileAsync(); 

ピック操作から取得したらStorageFile、それに対して必要な操作を実行できます。


ピッカーからの選択が返されるまで、実行を停止する必要があります。基本的に、これは上記の行で処理されます。

さらに、は待機していない非同期呼び出しでもあることMessageDialogがわかります。ShowAsync使用法は次のとおりです。

var messageDialog = new MessageDialog(...);
await messageDialog.ShowAsync();

以下:

await new MessageDialog('','').ShowAsync();

Microsoft は、使用Async方法をより明確にするために、async として宣言されたすべてのメソッドにサフィックスを使用するというこのガイドラインを適用しました。こちらも使ったほうがいいと思います。

良い習慣として、非同期呼び出しを起動する場合、ある時点でそれを待機する必要があります。そうしないと、予測できない結果が発生し、ほとんどの場合アプリケーションがクラッシュする可能性があります。


また、同じ種類のメッセージ ダイアログを 2 つ表示したい場合にも、この種類の例外が発生します。一度に画面に表示できるメッセージ ダイアログは 1 つだけです。最初のメッセージ ダイアログが既に表示されている間に、2 番目のメッセージ ダイアログは をスローする操作を試み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();
    }
}

CompletedPickerのイベントのイベント ハンドラーを追加する必要はありません。呼び出しが完了したlogFile後、コードをそのまま実行するだけで十分です。PickSingleFileAsyncあなたのロジックを認識していないため、完全に機能するコードを提供することはできません。ただし、いずれにせよ、呼び出しも確認してくださいawait( OpenStreamForReadAsyncMSDNドキュメント)。

于 2014-12-08T15:51:02.167 に答える