Xbox One CopyAsync 仅在零售模式下失败

Xbox One CopyAsync failing in Retail Mode only

基本上,以下代码将整个文件夹从应用程序安装复制到 LocalCacheFolder,因此它们可以 manipulated/updated。在本例中,名为 'Data'

的文件夹的内容

此代码在开发模式下的移动设备、台式机和 Xbox 上运行良好,但在零售模式下的 Xbox 上此行失败:

await file.CopyAsync(destinationFolder, file.Name, NameCollisionOption.FailIfExists);

这也是全新安装,所以我知道文件不存在。

在零售模式下是否有不同的方法来实现这一点,尽管理论上所有 UWP 代码都应该跨设备工作。

private async Task setupdatabase()
{
    StorageFolder destinationContainer = Windows.Storage.ApplicationData.Current.LocalCacheFolder;
    string root = Windows.ApplicationModel.Package.Current.InstalledLocation.Path;
    string path = root + @"\Data";

    StorageFolder sfolder = await StorageFolder.GetFolderFromPathAsync(path);

    await CopyFolderAsync(sfolder, destinationContainer);
}

public static async Task CopyFolderAsync(StorageFolder source, StorageFolder destinationContainer, string desiredName = null)
{
    StorageFolder destinationFolder = null;
    destinationFolder = await destinationContainer.CreateFolderAsync(desiredName ?? source.Name, CreationCollisionOption.OpenIfExists);

    foreach (var file in await source.GetFilesAsync())
    {
         await file.CopyAsync(destinationFolder, file.Name, NameCollisionOption.FailIfExists);
    }

    foreach (var folder in await source.GetFoldersAsync())
    {
         await CopyFolderAsync(folder, destinationFolder);
    }
}

我不确定是否会出现这种情况,因为您的代码看起来不错,但是 当 运行 应用在本地授予它一些权限时。也许在这种情况下也有不同的权限(对于 device/retail?) - 因此,您可以尝试不通过其路径而是直接使用 StorageFolder 访问该文件夹吗?像这样:

private async Task setupdatabase()
{
    StorageFolder sfolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Data");
    await CopyFolderAsync(sfolder, ApplicationData.Current.LocalCacheFolder);
}

public static async Task CopyFolderAsync(StorageFolder source, StorageFolder destinationContainer, string desiredName = null)
{
    StorageFolder destinationFolder = await destinationContainer.CreateFolderAsync(desiredName ?? source.Name, CreationCollisionOption.OpenIfExists);

    var existingItems = await destinationFolder.GetFilesAsync(); // to check if files are already there
    foreach (var file in (await source.GetFilesAsync()).Where(x => !existingItems.Any(y => y.Name == x.Name)))
    {
        await file.CopyAsync(destinationFolder, file.Name);
    }

    foreach (var folder in await source.GetFoldersAsync())
    {
        await CopyFolderAsync(folder, destinationFolder);
    }
}

在第二种方法中,我更改了 FailIfExists 现有项目的 check-up 属性 - 以防出现问题。

似乎是零售模式下 Xbox 上 CopyAsync 的错误

正在替换:

await file.CopyAsync(destinationFolder, file.Name, NameCollisionOption.FailIfExists);

与:

StorageFile sourcefile = null;
string sourcefiletext = null;
            try
            {
                sourcefile = await source.GetFileAsync(file.Name);
                sourcefiletext = await FileIO.ReadTextAsync(sourcefile);
            }
            catch (Exception e)
            {
                Debug.WriteLine "Read source error:" + e.ToString();
            }

            try
            {

                StorageFile destfile = await destinationFolder.CreateFileAsync(file.Name, CreationCollisionOption.FailIfExists);
                await Windows.Storage.FileIO.WriteTextAsync(destfile, sourcefiletext);
            }
            catch (Exception e)
            {
                Debug.WriteLine "Write dest error:" + e.ToString();
            }

基本上将其分成 2 个单独的操作解决了问题,我的应用程序现在可以正常运行。现在正在作为错误报告提交

更新:不完全是错误,而是 Microsoft 的一项功能:

这里的问题是包安装文件夹在 Xbox 零售模式下是加密的。包有权读取它自己的文件,这就是 ReadTextAsync+WriteTextAsync 起作用的原因。另一方面,CopyAsync 尝试复制具有与文件关联的所有属性(包括加密)的文件。