2014-12-22 4 views
0

에서 다운로드 한 후 즉시 파일을 열 수 없으며 열 수 없으며 이미지 원본으로 스트림을 즉시 사용할 수 없습니다. 대신, "Error HRESULT E_FAIL이 COM 구성 요소 호출에서 반환되었습니다"예외가 발생하지 않을 때까지 내 응용 프로그램을 대기 루프에서 실행하여 개방을 다시 시도해야합니다. 또는 앱이 사용자에게 조치를 다시 시도해야 함을 알려야합니다. 약 1 초 후에 파일을 열고 스트림을 이미지 소스로 사용할 수 있습니다. 이 문제는 처음에 JPG 파일을 오프라인에서 사용할 수없고 앱에서 다운로드 한 경우 발생합니다. 아무도 그 문제에 대한 더 나은 해결책을 가지고 있는지 알고 싶습니다. 나는 "온라인 전용"파일을 열 다시 시도Windows 8.1에서 OneDrive에서 JPG 파일을 성공적으로 다운로드 한 후 OneDrive

private async void LoadFileButton_Click(object sender, RoutedEventArgs e) 
    { 
     FileOpenPicker picker = new FileOpenPicker(); 
     picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; 
     picker.ViewMode = PickerViewMode.Thumbnail; 
     picker.FileTypeFilter.Add(".png"); 
     picker.FileTypeFilter.Add(".jpe"); 
     picker.FileTypeFilter.Add(".jpeg"); 
     picker.FileTypeFilter.Add(".jpg"); 
     picker.FileTypeFilter.Add(".gif"); 

     Stream stream = null; 
     StorageFile file = await picker.PickSingleFileAsync(); 
     if (file != null) 
     { 
      var basicProperties = await file.GetBasicPropertiesAsync(); 
      var props = await basicProperties.RetrievePropertiesAsync(
           new string[] { "System.OfflineAvailability", "System.StorageProviderFileRemoteUri" }); 
      if (props.ContainsKey("System.OfflineAvailability")) 
      { 
       var offline = (uint)props["System.OfflineAvailability"]; 
       if (offline == 0) 
       { 
        if (file.Provider.DisplayName == "OneDrive") 
        { 
         if (props.ContainsKey("System.StorageProviderFileRemoteUri")) 
         { 
          var uri = (string)props["System.StorageProviderFileRemoteUri"]; 
          var res = await GameStorage.DownloadOneDriveFile(file, uri, _downloadProgressBar); 
          if (res is string) 
          { 
           await App.InformUserAsync(res.ToString(), _title.Text); 
           return; 
          } 
          stream = (Stream)res; 
         } 
        } 
        else 
        { 
         await App.InformUserAsync(String.Format(
           App.GetString("MakeFileOfflinePrompt", "GameManagement"), 
           file.Path), _title.Text); 
         return; 
        } 
       } 
      } 
      if (stream == null) 
      { 
       stream = await file.OpenStreamForReadAsync(); 
      } 
      await _photoClipper.SetDisplayImageStreamAsync(stream); 
      _clipPhotoButton.IsEnabled = true; 
     } 
    } 
internal static async Task<object> DownloadOneDriveFile(StorageFile file, string url, 
                  ProgressBar progressBar = null) 
    { 
     if (progressBar != null) 
     { 
      progressBar.Visibility = Visibility.Visible; 
      progressBar.Value = 1; 
     } 
     if (__liveClient == null) 
     { 
      var msg = await ConnectLive(); 
      if (!String.IsNullOrEmpty(msg)) 
      { 
       return msg; 
      } 
     } 
     var uri = new Uri(WebUtility.UrlDecode(url)); 
     var pathElements = uri.LocalPath.Split(new char[] { '/' }, 
               StringSplitOptions.RemoveEmptyEntries); 
     var parentId = "folder." + pathElements[0]; 
     IDictionary<string, object> props = null; 

     for (var i = 1; i < pathElements.Length; i++) 
     { 
      props = await FindOneDrivePathElement(parentId, pathElements[i]); 
      if (props == null) 
      { 
       return String.Format(App.GetString("OneDrivePathElementNotFound", 
            "GameManagement"), pathElements[i], uri); 
      } 
      parentId = props["id"].ToString(); 
      if (progressBar != null) progressBar.Value += 1; 
     } 
     try 
     { 
      var operation = await __liveClient.CreateBackgroundDownloadAsync(parentId + 
               "/content", file); 
      LiveDownloadOperationResult result = null; 

      if (progressBar != null) 
      { 
       progressBar.Value = 10; 
       var progressHandler = new Progress<LiveOperationProgress>(
        (progress) => { progressBar.Value = progress.ProgressPercentage; }); 
       var cts = new CancellationTokenSource(); 
       result = await operation.StartAsync(cts.Token, progressHandler); 
      } 
      else 
      { 
       result = await operation.StartAsync(); 
      } 
      var trialsCount = 0; 
      string openErr = null; 
      Stream stream = null; 

      while (trialsCount < 5) 
      { 
       try 
       { 
        stream = await result.File.OpenStreamForReadAsync(); 
        break; 
       } 
       catch (Exception ex) 
       { 
        openErr = ex.Message; 
       } 
       trialsCount += 1; 
       await App.SuspendAsync(1000); 
      } 
      if (stream != null) 
      { 
       return stream; 
      } 
      return String.Format(App.GetString("OneDriveCannotOpenDownloadedFile", 
               "GameManagement"), file.Path, openErr); 
     } 
     catch (Exception ex) 
     { 
      return String.Format(App.GetString("OneDriveCannotDownloadFile", 
               "GameManagement"), file.Path, ex.Message); 
     } 
     finally 
     { 
      if (progressBar != null) 
      { 
       progressBar.Visibility = Visibility.Collapsed; 
      } 
     } 
    } 
private static async Task<IDictionary<string, object>> FindOneDrivePathElement(
                  string parentId, string childName) 
    { 
     var res = await __liveClient.GetAsync(parentId + "/files"); 

     if (res.Result.ContainsKey("data")) 
     { 
      var items = (IList<object>)res.Result["data"]; 

      foreach (var item in items) 
      { 
       var props = (IDictionary<string, object>)item; 
       if (props.ContainsKey("name")) 
       { 
        var name = props["name"].ToString(); 
        if (name == childName) 
        { 
         if (props.ContainsKey("id")) 
         { 
          return props; 
         } 
        } 
       } 
      } 
     } 
     return null; 
    } 
+0

StorageFile "IsAvailable"(즉, 오프라인에서 사용할 수 있거나 온라인 + 장치가 인터넷에 연결되어 있음)이 StorageFile의 스트림에 액세스하면 콘텐츠를 가져 오기에 충분해야합니다. 내가 왜 시나리오를 직접 처리하려고하는지 궁금하네요? – Brad

+0

System.IO.Exception 때문에 "이 시나리오를 처리하려고합니다."오류 HRESULT E_FAIL이 COM 구성 요소 호출에서 반환되었습니다. " 컴퓨터가 인터넷에 연결되어있는 동안 "온라인 전용"으로 사용할 수있는 파일을 열려고하면 throw됩니다. 내 컴퓨터에서 이것은 재현 가능합니다. OneDrive에서 파일을 마우스 오른쪽 단추로 클릭하고 "온라인 전용으로 설정"을 선택하면 파일을 더 이상 내 응용 프로그램에서 열 수 없습니다. – PaulBiz

답변

0

과 기적으로 예외 "오류 HRESULT E_FAIL는"더 이상 발생하지 않은 : 여기에 내 코드의 일부이다. 어떤 이유에서인지, 나는 모른다. 그러나, 나는 정말로 혼자서 그 시나리오를 다룰 필요가 없다. 감사.

+0

질문에 답변 해 주셔서 감사합니다. 다른 사람들에게 도움이되기를 바랍니다. – Brad

관련 문제