在Windows 8.1下成功从OneDrive下载JPG文件后,我无法打开它并立即将该流用作图像源。相反,我的应用程序必须在等待循环中运行才能重试打开,直到异常“错误HRESULT E_FAIL已从调用COM组件返回”不再发生。或者应用程序必须通知用户重试该操作。大约一秒左右后,可以打开文件,流可以用作图像源。如果JPG文件最初不能脱机使用并且我的应用程序下载它,则会出现此问题。我想知道是否有人有更好的解决方案来解决这个问题。以下是我的一些代码:
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 :(得分:0)
我再次尝试打开“可用的在线”文件,并且奇迹般的“错误HRESULT E_FAIL”不再发生。出于何种原因,我不知道。但是,我真的不需要自己处理这种情况。感谢。