Hello everyone.

The Mixed Reality Forums here are no longer being used or maintained.

There are a few other places we would like to direct you to for support, both from Microsoft and from the community.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.

If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.

And always feel free to hit us up on Twitter @MxdRealityDev.
Options

OneDrive + Unity

Is there a recommended path for pulling files from OneDrive into a Unity application? I see the OneDrive C# SDK is an option, but it looks like that requires writing a wrapper DLL to get it working in a Unity app. Is there a more straightforward approach?

Best Answer

Answers

  • Options

    ye.. dont wrap any dll... just do #if UNITY_UWP your uwp code #endif. but yes thats kind of a pain so better wrap that dll :)

    Healthcare IT professional by day - Indie GameDev for UWP and mobile platforms by night

  • Options
    sptspt ✭✭
    edited August 2016

    This is a good question.

    I have only been able to get downloading from a normal http server to work using the WWW component.

    I have not figured out how to get it to work from one drive or google drive. These both use some sort of api. I tried accessing google drive with a C++ app, but was stymied when I found that the package for security certificates is not present. There is a way to access google drive without https, but it still requires security credentials which makes it not general purpose, so I quit trying.

  • Options
    ContextVRContextVR ✭✭✭
    Answer ✓

    @Caleb_Cannon OneDrive provides FileOpenPicker and FileSavePicker contracts, so it should come up when you're using those contracts from within a C# application. Check out "File pickers" section in the description of HoloLens app model: https://developer.microsoft.com/en-us/windows/holographic/app_model

  • Options

    @ContextVR Fantastic! Just what I was looking for. Thanks!

  • Options

    Trying to use a FileOpenPicker directly in Unity is giving me an invalid window handle exception. The attached script is the test I was using. It throws the exception exactly when PickSingleFileAsync is called.

    using UnityEngine;
    using System;
    using System.Collections;
    
    #if WINDOWS_UWP
    
    using Windows.Storage.Pickers;
    using Windows.Storage;
    
    public class FilePickerTest : MonoBehaviour
    {
        FileOpenPicker openPicker;
    
        public void Start()
        {
            Debug.Log("Started (UWP)");
        }
    
        public void OpenFile()
        {
            OpenFileAsync();
        }
    
        private async void OpenFileAsync()
        {
            openPicker = new FileOpenPicker();
            openPicker.ViewMode = PickerViewMode.Thumbnail;
            openPicker.SuggestedStartLocation = PickerLocationId.Objects3D;
            openPicker.FileTypeFilter.Add(".fbx");
    
            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                // Application now has read/write access to the picked file
                Debug.Log("Picked file: " + file.DisplayName);
            }
            else
            {
                // The picker was dismissed with no selected file
                Debug.Log("File picker operation cancelled");
            }
        }
    }
    
    #else
    
    public class FilePickerTest : MonoBehaviour 
    {
        public void Start()
        {
            Debug.Log("Started (Editor)");
        }
    
        public void OpenFile()
        {
        }
    }
    
    #endif
    
  • Options

    Does anyone have any suggestions on overcoming the "Invalid Window Handle" issue Caleb ran into? I'm having the same problem. Past solutions in older regular Windows forums pointed to the lack of at least one FileTypeFilter and also using System; which I did both. No matter what I've tried, I still get the Invalid Window Handle.

  • Options

    When you build the project from Unity are you picking D3D or XAML?

    ===
    This post provided as-is with no warranties and confers no rights. Using information provided is done at own risk.

    (Daddy, what does 'now formatting drive C:' mean?)

  • Options

    file picker / saver work fine if you build to XAML... but if you need proper integration with OneDrive, you have to use the SDK, its rather easy to use though... I dint wrap the dlll for unity, i just code that part in Visual Studio solution.

    Healthcare IT professional by day - Indie GameDev for UWP and mobile platforms by night

  • Options

    We are using XAML as we have need for TextInput fields

  • Options

    @DanglingNeuron said:
    file picker / saver work fine if you build to XAML... but if you need proper integration with OneDrive, you have to use the SDK, its rather easy to use though... I dint wrap the dlll for unity, i just code that part in Visual Studio solution.

    I did have the SDK working in the Visual Studio Solution at one point but then when going back to Unity I had a bunch of errors. Do I just need to bracket the calls to the SDK with UNITY_EDITOR blocks?

  • Options

    There are several ways to accomplish this... I simply dont keep the OneDrive code in unity project at all. I just have Actions/Callbacks defined in unity project. The generated visual studio solution has extra code that hooks into those actions/callbacks and then use one drive sdk to perform the tasks and send data back to unity. So this code is completely separated from Unity projects.

    Healthcare IT professional by day - Indie GameDev for UWP and mobile platforms by night

  • Options

    @Caleb_Cannon and @EdElliott57: on the "invalid window handle" exception:
    Try adding UnityEngine.WSA.Application.InvokeOnUIThread around your code in OpenFileAsync() since the FileOpenPicker needs to be executed on the UI thread. I can't take credit for this solution, but it seems to work:

    private async void OpenFileAsync()
    {
        UnityEngine.WSA.Application.InvokeOnUIThread(async() =>
        {
            openPicker = new FileOpenPicker();
            openPicker.ViewMode = PickerViewMode.Thumbnail;
            openPicker.SuggestedStartLocation = PickerLocationId.Objects3D;
            openPicker.FileTypeFilter.Add(".fbx");
    
            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                // Application now has read/write access to the picked file
                Debug.Log("Picked file: " + file.DisplayName);
            }
            else
            {
                // The picker was dismissed with no selected file
                Debug.Log("File picker operation cancelled");
            }
        }, false);
    }
    
  • Options

    @Jeff your wrap with InvokeOnUIThread works but how do you get back into the rendering thread (if that's what it is called) after you get the file name? It might be fundamental to Unity folks so pre-apologizing for the extra question.

  • Options

    @Jeff
    i able to select image on one drive now i want to display that image in 3d Gameobject (Plane)... so how can i do this. ? please help

    Thanks in Advanced

  • Options

    I had OneDrive + FileOpenPicker working, but now it does not. When I run the example included below, it changes over to the HoloShell but does not show a FileOpenPicker as it did before. I am having a hard time tracking this problem down as it fails silently across threads. FileSavePicker works fine. Does anyone have any insight?

    I then upgraded to Unity 5.5.0f3 and it had the same problem. Upgraded HoloToolKit to 1.55 and same problem. Since it uses interfaces between Unity, HoloShell, and OneDrive it could be silently failing in any one of them. Any insights on debugging this problem?

    using System;
    using UnityEngine;
    #if NETFX_CORE
    using Windows.Storage;
    using Windows.Storage.Pickers;
    #endif
    
    public class PickFileBehavior : MonoBehaviour {
        // add this script to scene / project GameObject created with HoloToolkit 
        // add textmesh to GameObject as child of main camera +1m in Z, 
        // use editor to place it on UserNoticeTextMesh field in inspector 
        [Tooltip("Set User Notice Text")]
        public TextMesh UserNoticeTextMesh;
    
        public void UserMessage(string theMsg) {
            Debug.Log(theMsg);
            UserNoticeTextMesh.text = theMsg;
        }
    
        void Start() {
            UserMessage("Pick File Using F Key");
        }
    
        void Update() {
            if (Input.GetKeyUp(KeyCode.F))
            {
    #if NETFX_CORE
                SelectFile(SetLoadFile);
    #else
                UserMessage("PickFileBehavior: Pick Not Supported in Unity Editor");
    #endif
            }
        }
    
    #if NETFX_CORE
        private void SetLoadFile(StorageFile theFile) {
            if (theFile != null)
                UserMessage("Picked File " + theFile.Path);
            else
                UserMessage("Null File");
        }
    
        public void SelectFile(Action<StorageFile> selectAction) {
            UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
            {
                FileOpenPicker thePicker = new FileOpenPicker();
                thePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
                thePicker.ViewMode = PickerViewMode.List;
                thePicker.CommitButtonText = "OK";
                thePicker.FileTypeFilter.Add("*");
                StorageFile aFile = await thePicker.PickSingleFileAsync();
                UnityEngine.WSA.Application.InvokeOnAppThread(
                    () => { selectAction(aFile); }, true);
            }, false);
        }
    #endif
    }
    
  • Options

    @randyiform any luck overcoming the above issue?

  • Options

    Thanks for this thread -- it was helpful. Below is my code that works based on the above. A file is fetched from OneDrive and its name is displayed in a text field. 2 ways of using InvokeOnAppThread are demonstrated.

    My toolchain:
    -- Mixed Reality Toolkit v.2017.2.1.3 Hot Fix
    -- Unity 2017.2.1p2
    -- Visual Studio Community 2017 (15.6.1)
    -- HoloLens OS v.10.0.14393.2125
    -- Windows 10 v.1709 (Fall Creator's Edition)

    code:

        using System.Collections;
        using System.Collections.Generic;
        using UnityEngine; 
        using System.Diagnostics;
        using System.Runtime.CompilerServices;
        using System.Threading;
        using System.Threading.Tasks;
        using System;
        using UnityEngine.WSA;
        using UnityEngine.UI;
    
        #if ENABLE_WINMD_SUPPORT
        using Windows.Storage;
        using Windows.Storage.Streams;
        using Windows.Storage.Pickers;
        #endif
    
        public class AsyncSample : MonoBehaviour { 
            public Text label;
            public GameObject cube;
    
        #if ENABLE_WINMD_SUPPORT 
            private FileOpenPicker openPicker;
        #endif
    
            void Start()
            { 
                UnityEngine.Debug.LogFormat( "UnityThread: {0}", Thread.CurrentThread.ManagedThreadId ); 
    
        #if ENABLE_WINMD_SUPPORT  
                UnityEngine.WSA.Application.InvokeOnUIThread(OpenFileAsync, false);  
        #else
                UnityEngine.Debug.Log( "ENABLE_WINMD_SUPPORT false" ); 
        #endif 
            } 
    
            void ThreadCallback()
            {
                UnityEngine.Debug.LogFormat( "ThreadCallback() on thread: \t{0}", Thread.CurrentThread.ManagedThreadId );
    
                cube.transform.Rotate( Vector3.forward, 25f );
            } 
    
        #if ENABLE_WINMD_SUPPORT
            public async void OpenFileAsync()
            {  
                UnityEngine.Debug.LogFormat( "OpenFileAsync() on Thread: {0}", Thread.CurrentThread.ManagedThreadId );
    
                openPicker = new FileOpenPicker();
    
                //openPicker.ViewMode = PickerViewMode.Thumbnail;
                //openPicker.SuggestedStartLocation = PickerLocationId.Objects3D;
                //openPicker.FileTypeFilter.Add(".fbx");
                openPicker.FileTypeFilter.Add("*");
    
                StorageFile file = await openPicker.PickSingleFileAsync();
                string labelText = String.Empty;
                if ( file != null )
                {
                    // Application now has read/write access to the picked file 
                    labelText = "Picked file: " + file.DisplayName;
                }
                else
                {
                    // The picker was dismissed with no selected file 
                    labelText = "File picker operation cancelled";
                }
    
                UnityEngine.Debug.Log( labelText );
    
                UnityEngine.WSA.Application.InvokeOnAppThread( ThreadCallback, false );
    
                UnityEngine.WSA.Application.InvokeOnAppThread( new AppCallbackItem( () => { label.text = labelText; } ), false );
            }
        #endif
    
        }  
    
  • Options

    Thanks for this thread -- it was helpful. Below is my code that works. It opens OneDrive and after you select a file it displays the filename in a text field in the app. I included 2 methods of using InvokeOnAppThread.

    Toolchain:
    -- Mixed Reality Toolkit v.2017.2.1.3 Hot Fix
    -- Unity 2017.2.1p2
    -- Visual Studio Community 2017 (15.6.1)
    -- HoloLens OS v.10.0.14393.2125
    -- Windows 10 v.1709 (Fall Creator's Edition)

      
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine; 
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.Threading;
    using System.Threading.Tasks;
    using System;
    using UnityEngine.WSA;
    using UnityEngine.UI;
    
    #if ENABLE_WINMD_SUPPORT
    using Windows.Storage;
    using Windows.Storage.Streams;
    using Windows.Storage.Pickers;
    #endif
     
    public class AsyncSample : MonoBehaviour { 
        public Text label;
        public GameObject cube;
    
    #if ENABLE_WINMD_SUPPORT 
        private FileOpenPicker openPicker;
    #endif
          
        void Start()
        { 
            UnityEngine.Debug.LogFormat( "UnityThread: {0}", Thread.CurrentThread.ManagedThreadId ); 
    
    #if ENABLE_WINMD_SUPPORT  
            UnityEngine.WSA.Application.InvokeOnUIThread(OpenFileAsync, false);  
    #else
            UnityEngine.Debug.Log( "ENABLE_WINMD_SUPPORT false" ); 
    #endif 
        } 
             
        void ThreadCallback()
        {
            UnityEngine.Debug.LogFormat( "ThreadCallback() on thread: \t{0}", Thread.CurrentThread.ManagedThreadId );
             
            cube.transform.Rotate( Vector3.forward, 25f );
        } 
                   
    #if ENABLE_WINMD_SUPPORT
        public async void OpenFileAsync()
        {  
            UnityEngine.Debug.LogFormat( "OpenFileAsync() on Thread: {0}", Thread.CurrentThread.ManagedThreadId );
    
            openPicker = new FileOpenPicker();
     
            //openPicker.ViewMode = PickerViewMode.Thumbnail;
            //openPicker.SuggestedStartLocation = PickerLocationId.Objects3D;
            //openPicker.FileTypeFilter.Add(".fbx");
            openPicker.FileTypeFilter.Add("*");
         
            StorageFile file = await openPicker.PickSingleFileAsync();
            string labelText = String.Empty;
            if ( file != null )
            {
                // Application now has read/write access to the picked file 
                labelText = "Picked file: " + file.DisplayName;
            }
            else
            {
                // The picker was dismissed with no selected file 
                labelText = "File picker operation cancelled";
            }
            
            UnityEngine.Debug.Log( labelText );
    
            UnityEngine.WSA.Application.InvokeOnAppThread( ThreadCallback, false );
    
            UnityEngine.WSA.Application.InvokeOnAppThread( new AppCallbackItem( () => { label.text = labelText; } ), false );
        }
    #endif
    
    }
    
Sign In or Register to comment.