【问题标题】:Different app behaviour when deployed locally and from Store本地部署和从应用商店部署时的不同应用行为
【发布时间】:2015-03-08 15:53:29
【问题描述】:

从 Windows 应用商店(测试版)部署应用时,我遇到了奇怪的问题。该应用程序编写为 Windows Phone 8.1 RunTime。

我有一个用 C++/C# 编写的小型 Windows 运行时组件,用于检查文件是否存在:

bool FileEx::FileExists(String^ path)
{
    std::wstring pathW(path->Begin());
    std::string myPath(pathW.begin(), pathW.end());
    FILE *file = NULL;
    if (fopen_s(&file, myPath.c_str(), "r") == 0)
    {
         fclose(file);
         return true;
    }
    else return false;
}

测试方法:

现在让我们用两个文件来测试它 - 一个在本地文件夹中创建,一个在 MusicLibrary 的文件夹中。一切都在主项目中完成,在 C++/C# 中使用上述方法引用了 WRC。

const string localFileName = "local.txt";
const string musicFileName = "music.txt";
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFolder musicFolder = await KnownFolders.MusicLibrary.CreateFolderAsync("MyFolder", CreationCollisionOption.OpenIfExists);
await localFolder.CreateFileAsync(localFileName, CreationCollisionOption.ReplaceExisting); // create local file
await musicFolder.CreateFileAsync(musicFileName, CreationCollisionOption.ReplaceExisting); // create file in MusicLibrary

a) 本地文件 拳头——用纯C#测试:

// First check with C# if file exists - LOCAL FILE
StorageFile checkFile = null;
try { checkFile = await localFolder.GetFileAsync(localFileName); }
catch { checkFile = null; }
if (checkFile != null) await Trace.WriteLineAsync(false, "File exists with path = {0}", checkFile.Path);
else await Trace.WriteLineAsync(false, "File doesn't exist with path = {0}", checkFile.Path);

其次是书面组件:

Exception exc = null;
bool check = false;
try
{
    string path = string.Format(@"{0}\{1}", localFolder.Path, localFileName);
    await Trace.WriteLineAsync(false, "Attempt with WRC path = {0}", path);
    check = FileEx.FileExists(path);
}
catch (Exception ex) { exc = ex; }
if (exc != null) await Trace.WriteLineAsync(false, "Exception WRC");
else await Trace.WriteLineAsync(false, "No exception WRC, file exists = {0}", check);

b) 与音乐库文件夹中的文件相同:

拳头——用纯C#测试:

checkFile = null;
try { checkFile = await musicFolder.GetFileAsync(musicFileName); }
catch { checkFile = null; }
if (checkFile != null) await Trace.WriteLineAsync(false, "File exists with path = {0}", checkFile.Path);
else await Trace.WriteLineAsync(false, "File doesn't exist with path = {0}", checkFile.Path);

其次是书面组件:

check = false;
exc = null;
try
{
   string path = string.Format(@"{0}\{1}", musicFolder.Path, musicFileName);
   await Trace.WriteLineAsync(false, "Attempt with WRC path = {0}", path);
   check = FileEx.FileExists(path);
}
catch (Exception ex) { exc = ex; }
if (exc != null) await Trace.WriteLineAsync(false, "Exception WRC");
else await Trace.WriteLineAsync(false, "No exception WRC, file exists = {0}", check);

结果:

在任何情况下都不例外,正如纯 C# 方法所示,这两个文件在创建后都存在。如下图所示,当通过 Visual Studio 部署应用程序时,它可以正常工作,运行时组件显示两个文件,但是当从商店下载应用程序时,情况有所不同 - WRC 方法适用于本地文件,但是不适用于 MusicLibrary 中的这些。

问题:

在这两种情况下,文件路径都是相同的,在两种部署中运行时组件都有效,因此第一个文件存在。尽管在 packageappx.manifest 文件中设置了所有必要的功能(本地部署有效),但 Windows 运行时组件似乎无法访问 MusicLibrary。

有人知道为什么 Windows 运行时组件无法访问 MusicLibrary 中的文件吗? Windows 运行时组件是否需要一些额外的功能?
有什么办法让它工作吗?

【问题讨论】:

    标签: c# windows-runtime windows-phone windows-phone-8.1 c++-cx


    【解决方案1】:

    商店的行为是正确的:该应用对其已安装和应用数据文件夹之外的文件系统无权访问。 Win32 和 C 运行时函数直接访问文件,因此需要直接访问权限。

    StorageFile 类与文件代理一起使用,因此可以利用声明的功能等优势。代理代表应用程序读取文件并通过 StorageFile 流式传输文件内容。

    应用必须使用 StorageFile 在其应用数据和安装位置之外读取或写入文件

    我们已标记测试和生产之间的行为差​​异以供调查。

    【讨论】:

    • 当 Visual Studio 端加载应用程序进行调试时,它们具有授予过多文件系统权限的副作用。例如,您可以在侧面加载时写入安装文件夹(这是不允许的......)。
    • 感谢您的解释。据我了解,访问 WRC 中的文件(位于本地文件夹之外)的唯一方法是使用从 StorageFile 获得的 Stream。
    猜你喜欢
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多