1

我正在使用 FileOpenPicker 从 OneDrive 中选择一个文件,随后我将通过“标准”C++ 接口(不是 C++/WinRT)访问该文件。我知道这些接口无法访问 FileOpenPicker 返回的路径,因此我使用 StorageFile::CopyAsync 将文件复制到 ApplicationData 下的可访问位置。

这适用于桌面上的 UWP x64 构建,但在 HoloLens 2 上的 UWP arm64 构建中失败。

在 HoloLens 上,FileOpenPicker 仅提供文件的一小部分。例如,对于 OneDrive 上 2.83 MB 的文件,FileOpenPicker 和 CopyAsync 生成的文件只有 144.6 KB。我已经对 FileOpenPicker 提供的源文件和 CopyAsync 的目标文件的文件大小和完整性进行了测试——例如:

uint64_t sourceSize = sourceFile.GetBasicPropertiesAsync().get().Size();
bool sourceIncomplete
    = uint32_t (sourceFile.Attributes())
    & uint32_t (FileAttributes::LocallyIncomplete);

LocallyIncomplete 位是明确的,即使大小仅为 2.83 MB 中的 144.6 KB。

CopyAsync 然后成功地复制了它所提供的 144.6 KB,但后来由于 FileOpenPicker 中的源文件不完整且无效而失败。

HoloLens 2 缺少什么?


这是一个最小的可重现示例——从https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/FilePicker/cppwinrt的 Microsoft GitHub FilePicker 示例中对 Scenario1_SingleFile.cpp 稍作修改

为 UWP-arm64 编译,部署到 HoloLens 2,并在 OneDrive 上使用数兆字节的文件进行测试。


// Modified version of Scenario1_SingleFile.cpp
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

#include "pch.h"
#include "Scenario1_SingleFile.h"
#include "Scenario1_SingleFile.g.cpp"

#include <winrt/Windows.Storage.FileProperties.h>
#include <sstream>

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage;
using namespace Windows::Storage::Pickers;
using namespace Windows::UI::Xaml;

namespace winrt::SDKTemplate::implementation
{
    Scenario1_SingleFile::Scenario1_SingleFile()
    {
        InitializeComponent();
    }

    fire_and_forget Scenario1_SingleFile::PickAFileButton_Click(IInspectable const&, RoutedEventArgs const&)
    {
        auto lifetime = get_strong();

        // Clear previous returned file name, if it exists, between iterations of this scenario
        OutputTextBlock().Text(L"");

        FileOpenPicker openPicker;
        openPicker.ViewMode(PickerViewMode::Thumbnail);
        openPicker.SuggestedStartLocation(PickerLocationId::PicturesLibrary);
        openPicker.FileTypeFilter().ReplaceAll({ L".jpg", L".jpeg", L".png",
            // twhall@umich.edu added for "big" files:
            L".mp4", L".wmv", L".stl" });
        StorageFile file = co_await openPicker.PickSingleFileAsync();
        if (file != nullptr)
        {
            // Application now has read/write access to the picked file
#if 0
            OutputTextBlock().Text(L"Picked photo: " + file.Name());
#else
            // twhall@umich.edu:
            // *  Add feedback for file size and incompleteness.
            // *  Test on multi-megabyte files picked from OneDrive
            //    on the HoloLens (UWP-arm64)
            auto props = co_await file.GetBasicPropertiesAsync();
            uint64_t size = props.Size();
            uint32_t incomplete = (
                uint32_t (file.Attributes()) &
                uint32_t (FileAttributes::LocallyIncomplete));
            std::wstringstream text{};
            text << L"Picked file: "  << file.Name().c_str()
                 << L" (" << size << L" bytes, "
                 << (incomplete ? L"incomplete)" : L"complete)");
            OutputTextBlock().Text(text.str().c_str());
#endif
        }
        else
        {
            OutputTextBlock().Text(L"Operation cancelled.");
        }
    }
}
4

0 回答 0