에서 다운로드 한 후 즉시 파일을 열 수 없으며 열 수 없으며 이미지 원본으로 스트림을 즉시 사용할 수 없습니다. 대신, "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;
}
StorageFile "IsAvailable"(즉, 오프라인에서 사용할 수 있거나 온라인 + 장치가 인터넷에 연결되어 있음)이 StorageFile의 스트림에 액세스하면 콘텐츠를 가져 오기에 충분해야합니다. 내가 왜 시나리오를 직접 처리하려고하는지 궁금하네요? – Brad
System.IO.Exception 때문에 "이 시나리오를 처리하려고합니다."오류 HRESULT E_FAIL이 COM 구성 요소 호출에서 반환되었습니다. " 컴퓨터가 인터넷에 연결되어있는 동안 "온라인 전용"으로 사용할 수있는 파일을 열려고하면 throw됩니다. 내 컴퓨터에서 이것은 재현 가능합니다. OneDrive에서 파일을 마우스 오른쪽 단추로 클릭하고 "온라인 전용으로 설정"을 선택하면 파일을 더 이상 내 응용 프로그램에서 열 수 없습니다. – PaulBiz