简体   繁体   English

在 Hololens 上评估 OpenFilePicker 时调用 System.Exception

[英]System.Exception getting called when assessing OpenFilePicker on Hololens

I'm using the MRTK for a hololens app and I need to select a file that the user puts in their document folder.我正在将 MRTK 用于 hololens 应用程序,我需要 select 用户放入其文档文件夹中的文件。 I am trying to access the FileOpenPicker and use the PickSingleFileAsync() function from a button press to get the file and then load that into my app.我正在尝试访问 FileOpenPicker 并通过按下按钮使用 PickSingleFileAsync() function 来获取文件,然后将其加载到我的应用程序中。

The code inside this function is basically what I am doing:这个 function 里面的代码基本上就是我在做的:

(Code Source) (代码源)

private async void PickAFileButton_Click(object sender, RoutedEventArgs e)
        {
            // Clear previous returned file name, if it exists, between iterations of this scenario
            OutputTextBlock.Text = "";

            FileOpenPicker openPicker = new FileOpenPicker();
            openPicker.ViewMode = PickerViewMode.Thumbnail;
            openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            openPicker.FileTypeFilter.Add(".jpg");
            openPicker.FileTypeFilter.Add(".jpeg");
            openPicker.FileTypeFilter.Add(".png");
            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                // Application now has read/write access to the picked file
                OutputTextBlock.Text = "Picked photo: " + file.Name;
            }
            else
            {
                OutputTextBlock.Text = "Operation cancelled.";
            }
        }

However, when I build and deploy to the Hololens Emulator, when I press the button It runs through the first part of the code just fine but I get an exception on this line但是,当我构建并部署到 Hololens Emulator 时,当我按下按钮时,它会很好地运行代码的第一部分,但在这一行出现异常

StorageFile file = await openPicker.PickSingleFileAsync();

After extensive research and some frustration I made a very poor and vague post about it here .经过广泛的研究和一些挫折后,我在这里发表了一篇非常糟糕和模糊的帖子。

In that post I referenced this post which was made 2 years ago and says you can't do this but The Microsoft docs for Hololens say that you can use File pickers, in this case, FileOpenPicker.在那篇文章中,我引用了 2 年前发表的这篇文章,并说你不能这样做,但Hololens 的 Microsoft 文档说你可以使用文件选择器,在这种情况下是 FileOpenPicker。

I found this post buried in the Windows Mixed Reality Developer Forum that's related but isn't the issue I am having, I still felt it was necessary to include in this post.我发现这篇文章埋在 Windows 混合现实开发者论坛中,但不是我遇到的问题,我仍然觉得有必要将其包含在这篇文章中。

I also want to add that I do have a file picker app installed.我还想补充一点,我确实安装了一个文件选择器应用程序。 According to this post on Microsoft Docs if you call FileOpenPicker it will open whatever file picker was first installed on your device.根据Microsoft Docs 上的这篇文章,如果您调用 FileOpenPicker,它将打开您设备上首次安装的任何文件选择器。

Also in the MRTK and the Appx that is being generated I am ensuring the permission to "PictureLibrary" capability is enabled.同样在 MRTK 和正在生成的 Appx 中,我确保启用“PictureLibrary”功能的权限。

Any help would be greatly appreciated, I feel I've waited too long to make a more formal post on this topic and I'm hoping to have some answers.任何帮助将不胜感激,我觉得我已经等了太久才能就这个主题发表更正式的帖子,我希望能得到一些答案。 Thanks!谢谢!

ALL THANKS TO THIS POST!感谢这篇文章! I finally found a solution to my issue.我终于找到了解决我的问题的方法。 The biggest call that wasn't mentioned in any docs I looked through was this UnityEngine.WSA.Application.InvokeOnUIThread()在我浏览的任何文档中都没有提到的最大调用是这个UnityEngine.WSA.Application.InvokeOnUIThread()

I didn't run into this, nor did I find any documentation on this being a solution for MRTK+unity for hololens development.我没有遇到这个问题,也没有找到任何文档说明这是 MRTK+unity for hololens 开发的解决方案。 So for anyone out there looking for a solution to the issue I will quote that link above in case it's broken in the future.因此,对于在那里寻找问题解决方案的任何人,我将引用上面的链接,以防它在未来被破坏。

#if !UNITY_EDITOR && UNITY_WSA_10_0
        Debug.Log("***********************************");
        Debug.Log("File Picker start.");
        Debug.Log("***********************************");

        UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
        {
            var filepicker = new FileOpenPicker();
            // filepicker.FileTypeFilter.Add("*");
            filepicker.FileTypeFilter.Add(".txt");

            var file = await filepicker.PickSingleFileAsync();
            UnityEngine.WSA.Application.InvokeOnAppThread(() => 
            {
                Debug.Log("***********************************");
                string name = (file != null) ? file.Name : "No data";
                Debug.Log("Name: " + name);
                Debug.Log("***********************************");
                string path = (file != null) ? file.Path : "No data";
                Debug.Log("Path: " + path);
                Debug.Log("***********************************");

                

                //This section of code reads through the file (and is covered in the link)
                // but if you want to make your own parcing function you can 
                // ReadTextFile(path);
                //StartCoroutine(ReadTextFileCoroutine(path));

            }, false);
        }, false);

        
        Debug.Log("***********************************");
        Debug.Log("File Picker end.");
        Debug.Log("***********************************");
#endif

EDIT:编辑:

A little explanation as to what "InvokeOnUIThread" and "InvokeOnAppThread" mean.关于“InvokeOnUIThread”和“InvokeOnAppThread”含义的一点解释。

Think of the way your MRTK app runs on the hololens, you have the app running in it's own little environment with a MRTK specific unity engine handling function calls in your app.想想您的 MRTK 应用程序在 hololens 上运行的方式,您的应用程序在它自己的小环境中运行,并使用 MRTK 特定的统一引擎处理您的应用程序中的 function 调用。 That app is then running inside the bigger app (the OS) of the hololens.然后,该应用程序在 hololens 的更大应用程序(操作系统)中运行。 So whenever you make calls to UWP specific functions, things that only the hololens will understand, you NEED to call those functions inside the InvokeOnUIThread.因此,每当您调用 UWP 特定函数时,只有 hololens 才能理解的事情,您需要在 InvokeOnUIThread 中调用这些函数。 Now while you're running inside that function call if you need to make any function calls back to functions that are MRTK, unity, or your own creation you need to use InvokeOnAppThread.现在,当您在 function 调用中运行时,如果您需要对 MRTK、unity 或您自己创建的函数进行任何 function 调用,则需要使用 InvokeOnAppThread。 This essentially tells the application that you want to make some UWP function calls then at any point if you need to pass back any information from the UWP function calls while still inside the InvokeOnUIThread call, you need to use InvokeOnAppThread. This essentially tells the application that you want to make some UWP function calls then at any point if you need to pass back any information from the UWP function calls while still inside the InvokeOnUIThread call, you need to use InvokeOnAppThread.

From what I found out this is basically how this whole thing works and I figured this would be important to document.据我发现,这基本上就是整个事情的运作方式,我认为这对记录很重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM