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 尝试复制具有与文件关联的所有属性(包括加密)的文件。
基本上,以下代码将整个文件夹从应用程序安装复制到 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);
}
}
我不确定是否会出现这种情况,因为您的代码看起来不错,但是
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 尝试复制具有与文件关联的所有属性(包括加密)的文件。