Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从OneDrive下载后无法立即打开文件_C#_Windows_Onedrive - Fatal编程技术网

C# 从OneDrive下载后无法立即打开文件

C# 从OneDrive下载后无法立即打开文件,c#,windows,onedrive,C#,Windows,Onedrive,在Windows 8.1下成功从OneDrive下载JPG文件后,我无法立即打开它并将该流用作图像源。相反,我的应用程序必须在等待循环中运行,以重试打开,直到调用COM组件返回异常错误HRESULT E_FAIL不再发生为止。或者应用程序必须通知用户重试该操作。大约一秒钟后,文件可以打开,流可以用作图像源。如果JPG文件最初无法脱机使用,并且我的应用程序下载了它,则会出现此问题。我想知道是否有人能更好地解决这个问题。以下是我的一些代码: private async void LoadFileBu

在Windows 8.1下成功从OneDrive下载JPG文件后,我无法立即打开它并将该流用作图像源。相反,我的应用程序必须在等待循环中运行,以重试打开,直到调用COM组件返回异常错误HRESULT E_FAIL不再发生为止。或者应用程序必须通知用户重试该操作。大约一秒钟后,文件可以打开,流可以用作图像源。如果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;
    }

我再次尝试打开一个仅在线可用的文件,奇迹般地,异常错误HRESULT E_FAIL不再出现。不管什么原因,我都不知道。但是,我真的不需要自己处理这种情况。谢谢。

只要存储文件可用,即离线可用或在线可用+设备连接到Internet,只要访问存储文件流就足以获取内容。我很好奇你为什么要自己处理这个场景?我之所以要处理这个场景,是因为对COM组件的调用返回了System.IO.Exception错误HRESULT E_FAIL。当我试图打开一个仅在计算机连接到internet时才在线可用的文件时引发。在我的电脑上,这是可复制的:当右键单击OneDrive上的文件并选择“仅联机可用”时,该文件将无法在我的应用程序中打开。感谢您回答自己的问题-希望这将有助于其他人!