0

Basically the following code copies an entire folder from the app installation into the LocalCacheFolder so they can be manipulated/updated. In this case the contents of the folder called 'Data'

This code works fine on mobile, desktop and on Xbox in Dev Mode, but this line fails on Xbox in Retail Mode:

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

This is also on a fresh install so I know the file(s) don't already exist.

Is there a different way to achieve this in Retail Mode, although in theory all UWP code should work across devices.

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);
    }
}
4

2 回答 2

1

似乎是零售模式下 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 个单独的操作解决了问题,我的应用程序现在可以正常运行。这现在作为错误报告提交

更新:不是一个错误,而是一个功能,来自微软:

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

于 2017-02-14T18:16:24.993 回答
0

我不确定是否会出现这种情况,因为您的代码看起来不错,但是一旦我在本地运行应用程序时遇到了某种情况,就会授予它一些特权。也许在这种情况下也有不同的权限(对于设备/零售?) - 因此,您可以尝试不通过其路径而是直接使用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属性以检查现有项目 - 以防出现问题。

于 2017-02-14T07:02:49.013 回答