2014-12-08 3 views
0

В настоящее время я разрабатываю пример приложения Windows 8, который загружает файл журнала и обрабатывает его для показа в DevExpress XtraGrid. Когда я добавить необходимые расширения для фильтра Тип файла, код бросает UnauthorizedAccessException, даже если я добавил расширений файлов в appxmanifest:FileOpenPicker throws 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), который является, почему я задаю этот вопрос прямо здесь. Я признателен за любую помощь, оказанную здесь :)

UPDATE:

Когда COMException был брошен, то HRESULT всегда (0x80070005), но внутренняя HRESULT (отображаемая в окне Подробности HRESULT) была нормально -21474xxxx, но когда я отлаживаю свое приложение в VS с повышенным правом, внутренний HRESULT равен -2147024891.

+0

Что вы подразумеваете под «кодом выпрыгивает»? –

+0

Вы попробовали другой объект, предлагаемый для размещения, чем ComputerFolder? – Uwe

+0

@BenRobinson By «Код выпрыгивает», я имел в виду, что код больше не запускается и идет непосредственно к блоку catch. – AlphaNERD

ответ

1

Вам не кажется await звонок PickSingleFileAsync.

Вы должны делать что-то вроде этого:

StorageFile file = await picker.PickSingleFileAsync(); 

После вас есть StorageFile от операции Пика, вы можете выполнять любые операции, которые вы должны, против него.


Вы должны остановить выполнение до тех пор, пока не будет выбран выбор из сборщика. В основном, это обрабатывается для вас с помощью строки выше.

Кроме того, я вижу, что MessageDialogShowAsync также является асинхронным вызовом, который не ожидается. Использование должно быть:

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 случае Picker. Этого достаточно для запуска вашего кода, как и на logFile после завершения вызова PickSingleFileAsync. Я не могу предоставить полный рабочий код, потому что я не знаю вашей логики. Но в любом случае, убедитесь, что вы также await звоните OpenStreamForReadAsync (MSDN documentation).

+0

Спасибо за подсказку, я применил изменения, как показано в вашем ответе, но это все еще не работает. Visual Studio не разрешает оператор 'await' в блоке' catch' – AlphaNERD

+0

. Я добавил некоторые изменения, надеюсь, вы сможете разобраться сейчас, чтобы заставить его работать. Короче говоря, все призывы к методам с суффиксом Async должны быть ожидаемы. Прочтите немного больше об использовании асинхронного ожидания. – VasileF

+0

Это правда, вы не можете ждать в блоке catch. Но почему вы хотите отобразить ошибку таким образом? Это для целей отладки? Просто поставьте точку останова в блоке catch и посмотрите подробности о переменной «ex», которая содержит сведения об исключении. – VasileF

Смежные вопросы