question

Osaxely avatar image
1 Vote"
Osaxely asked RoyLi-MSFT edited

FileOpenPicker on Xbox One : Removed in latest SDK ?

Hello ! This is a post to maybe report a bug, or just indicate that there is a problem with the latest UWP SDK.
When I target the latest verion of the SDK in my UWP, the FileOpenPicker works very well on PC, but on Xbox One it returns null when user select a file.
Is the FileOpenPicker removed from the latest SDK on Xbox ?

windows-uwp
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

NicoZhu-MSFT avatar image
1 Vote"
NicoZhu-MSFT answered RoyLi-MSFT edited

Hello @Osaxely, Welcome to Micorosoft Q&A,

Currently, there is no such description that FileOpenPicker has been obsolete within Xob platform.
If you could reproduce this problem, please feel free post it with windows feed back hub app, and current workaround is modify the project 17763 as the Minimum build and select 1809 as Target build.



If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello ! Yes I could reproduce the problem, I will report it in Feedback Hub
I knew the solution of targeting.
Thank you very much !

1 Vote 1 ·
cubeof11 avatar image
0 Votes"
cubeof11 answered cubeof11 edited

I'm seeing similar symptoms in the following environment:

  • JavaScript application

  • Minimum version 10.0.10240.0 (initial version released July 2015)

  • Target version 10.0.19041.0 (version 2004, May 2020 Update)

  • Multi-user application (manifest uap:SupportedUsers = multiple)

The scenario is creating a picker using the Windows.Storage.Pickers.FileOpenPicker constructor (intended for single user applications) and then calling FileOpenPicker.PickSingleFileAsync or FileOpenPicker.PickMultipleFilesAsync. The picker appears to behave normally including while selecting a file, but there is a noticeable delay in user interface responsiveness after choosing a file, and the returned file is null. (Based on an experiment of deploying the "File picker provider sample" from the Universal Windows Platform (UWP) app samples modified to be a multi-user application, this might be the file picker basket throwing "Access is denied." (error code 0x80070005) when File Explorer calls Windows.Storage.Pickers.Provider.FileOpenPickerUI.AddFile.)

I switched to creating a file picker for multi-user applications (using FileOpenPicker.CreateForUser), but calling FileOpenPicker.PickSingleFileAsync or FileOpenPicker.PickMultipleFilesAsync would result in the error "Invalid window handle." (error code 0x80070578).

The workaround I settled on was catching that specific error code, then calling Windows.Storage.DownloadsFolder.CreateFolderForUserAsync with a made-up preset temporary folder name (and setting Windows.Storage.CreationCollisionOption.FailIfExists), and if that succeeded, then I immediately cleaned up that folder by calling StorageFolder.DeleteAsync. Regardless of whether the temporary folder was created or not, this prepares the file picker for the remaining running lifetime of the application, and you can retry calling the FileOpenPicker methods normally.

Note that this workaround does leave behind a folder in the Downloads folder named after your application that your application cannot delete automatically; if its presence bothers you or your users, you can have the user open a folder picker to the parent folder (the Downloads folder) and then you can delete that child folder, preferably after verifying that the child folder is still empty.

The DownloadsFolder workaround is implemented as the following; in Microsoft Visual Studio 2017, create a new JavaScript project using the "Blank App (Universal Windows)" template, set the minimum and target versions as described earlier, add <uap:SupportedUsers>multiple</uap:SupportedUsers> inside /Package/Properties to package.appxmanifest, and replace the contents of main.js with the following code:

Windows.UI.WebUI.WebUIApplication.onactivated = Application_Activate_FilePicker;

function Application_Activate_FilePicker(eventDetails)
{
    var sender = eventDetails.target;
    var activationEventArguments = eventDetails.detail[0];

    var user = activationEventArguments.user;

    var openPicker = BuildFileOpenPickerForUser(user);
    openPicker.pickSingleFileAsync().then(BindFunctionToContextOnce(Application_Activate_FilePicker_FilePicked, user), BindFunctionToContextOnce(Application_Activate_FilePicker_FilePickerFailed, user));
}

function Application_Activate_FilePicker_FilePicked(file)
{
    var user = this;
    if (file !== null)
    {
        window.setTimeout(BindFunctionToContextOnce(Application_Activate_FilePicker_DisplayFile, file), 1000);
    }
    else
    {
        window.setTimeout(Application_Activate_FilePicker_DisplayAbsence, 1000);
    }
}

function Application_Activate_FilePicker_DisplayFile()
{
    var file = this;
    new Windows.UI.Popups.MessageDialog("A file was selected:  " + file.name, "File Selected").showAsync();
}
function Application_Activate_FilePicker_DisplayAbsence()
{
    new Windows.UI.Popups.MessageDialog("No file was selected.", "No File Selected").showAsync();
}

function Application_Activate_FilePicker_FilePickerFailed(problem)
{
    var user = this;
    if (problem.number === -2147023496 /* ~~0x80070578 */)
    {
        if (user !== null)
        {
            var downloadsFolderClass = Windows.Storage.DownloadsFolder;
            if (downloadsFolderClass.createFolderForUserAsync !== void(0))
            {
                downloadsFolderClass.createFolderForUserAsync(user, "TemporaryFolder", Windows.Storage.CreationCollisionOption.failIfExists).then(BindFunctionToContextOnce(Application_Activate_FilePicker_TemporaryFolderCreated, user), BindFunctionToContextOnce(Application_Activate_FilePicker_TemporaryFolderFailed, user));
            }
        }
    }
}

function Application_Activate_FilePicker_TemporaryFolderCreated(storageFolder)
{
    var user = this;
    storageFolder.deleteAsync(Windows.Storage.StorageDeleteOption.permanentDelete).then(BindFunctionToContextOnce(Application_Activate_FilePicker_TemporaryFolderDeleted, user), BindFunctionToContextOnce(Application_Activate_FilePicker_TemporaryFolderFailed, user));
}

function Application_Activate_FilePicker_TemporaryFolderDeleted()
{
    var user = this;
    Application_Activate_FilePicker_TemporaryFolderFailed.call(user, null);
}

function Application_Activate_FilePicker_TemporaryFolderFailed(problem)
{
    var user = this;
    var openPicker = BuildFileOpenPickerForUser(user);
    openPicker.pickSingleFileAsync().then(BindFunctionToContextOnce(Application_Activate_FilePicker_FilePicked, user), BindFunctionToContextOnce(Application_Activate_FilePicker_FilePickerFailed, user));
}

function BindFunctionToContextOnce(targetFunction, targetObject)
{
    return function BindFunctionToContextOnce_Callback()
    {
        var localFunction = targetFunction;
        var localTarget = targetObject;
        targetFunction = null;
        targetObject = null;
        return localFunction.apply(localTarget, arguments);
    };
}

function BuildFileOpenPickerForUser(user)
{
    var fileOpenPickerClass = Windows.Storage.Pickers.FileOpenPicker;
    var openPicker;
    if ((user !== null) && (fileOpenPickerClass.createForUser !== void(0)))
    {
        openPicker = fileOpenPickerClass.createForUser(user);
    }
    else
    {
        openPicker = new fileOpenPickerClass();
    }
    openPicker.settingsIdentifier = "Specimen";
    openPicker.fileTypeFilter.replaceAll(["*"]);
    openPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.downloads;
    return openPicker;
}
· 7
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello, thanks for the answer!
I have noticed the same with FileSavePicker [Multi context user], it works on PC but crash on Xbox because "Invalid Windows handle".

0 Votes 0 ·

Both FileOpenPicker and FileSavePicker behave identically for this discussion, and the DownloadsFolder workaround applies to both. That said, if you are looking to provide file system features on Xbox One, I'd urge you to test out calling any necessary platform APIs early in the development process to see if there are any immediate obstacles that would prevent your product from functioning, especially if you are a multi-user application, since several additional APIs are not functional for those kinds of applications that cannot always be worked around by proxying the calls to a companion single user application, and the unsupported APIs are not identified in the documentation.

0 Votes 0 ·

Hello, don't worry for that, my app is already published and working using some filesystem features :)
I don't know if it's good, but I have used win32-and-com-for-uwp-apps and everything works perfectly without issues.

EDIT: The FolderPicker has same issue...crappy API, I will try your workaround.


0 Votes 0 ·
Show more comments