Windows 10通用应用程序的文件/目录访问

25

我正在开发一款应用程序,它可以从文件系统中的可配置位置读取jpeg和pdf文件。 目前已经实现了一个运行版本,使用的是WPF技术,现在我正在尝试迁移到新的Windows通用应用程序。

以下代码在WPF中可以正常工作:

public IList<string> GetFilesByNumber(string path, string number)
    {
        if (string.IsNullOrWhiteSpace(path))
            throw new ArgumentNullException(nameof(path));

        if (string.IsNullOrWhiteSpace(number))
            throw new ArgumentNullException(nameof(number));

        if (!Directory.Exists(path))
            throw new DirectoryNotFoundException(path);

        var files = Directory.GetFiles(path, "*" + number + "*",
           SearchOption.AllDirectories);

        if (files == null || files.Length == 0)
            return null;
        return files;
    }

使用通用应用程序时,我遇到了一些问题:

  • Directory.Exists 不可用
  • 我如何读取位于我的应用程序存储之外的目录?

要从应用程序存储之外的其他目录中读取,请尝试以下操作:

StorageFolder folder = StorageFolder.GetFolderFromPathAsync("D:\\texts\\");
var fileTypeFilter = new string[] { ".pdf", ".jpg" };
QueryOptions queryOptions = new QueryOptions(CommonFileQuery.OrderBySearchRank, fileTypeFilter);
queryOptions.UserSearchFilter = "142";
StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(queryOptions);
IReadOnlyList<StorageFile> files = queryResult.GetFilesAsync().GetResults();

问题是:它无法工作,但我收到了一个异常:

  

类型为'System.UnauthorizedAccessException'的异常发生在TextManager.Universal.DataAccess.dll中,但未在用户代码中处理      附加信息:拒绝访问。(HRESULT 异常值为0x80070005(E_ACCESSDENIED))

我知道你必须在清单中配置一些权限,但我找不到适合文件系统 IO 操作的权限...

是否有人也遇到过这样的问题/可能的解决方案?

解决方案: 从@Rico Suter给我的解决方案中,我选择了FutureAccessList与FolderPicker相结合。在程序重新启动后,也可以使用Token访问该条目。

我还可以向您推荐UX指南和这个Github示例

非常感谢!


1
为什么你想要读取应用存储之外的目录?沙盒存在是有原因的。 - user932887
2
因为我想要一个简单的方法来更改文件。这意味着,由于沙盒机制的存在,没有办法实现吗? - WhiteIntel
6个回答

51
在 UWP 应用中,你只能访问以下文件和文件夹:

如果你需要访问 D:\ 中的所有文件,则用户必须使用 FolderPicker 手动选择 D:\ 驱动器,然后你就可以访问该驱动器中的所有内容...

更新:

Windows 10 build 17134(2018年4月更新,版本号1803)为UWP应用程序增加了额外的文件系统访问功能:

  • 任何声明了AppExecutionAlias的UWP应用程序(无论是常规窗口应用程序还是控制台应用程序),当从命令行激活时,现在都被授予对当前工作目录及其下属文件和文件夹的隐式访问权限。当前工作目录是用户选择执行您的AppExecutionAlias的任何文件系统位置。

  • 新的broadFileSystemAccess功能授予应用程序与当前运行该应用程序的用户相同的文件系统访问权限,而无需出现文件选择器样式的提示。可以通过以下方式在清单中设置此访问权限:

    xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    ...
    IgnorableNamespaces="uap mp uap5 rescap">
    ...
    <Capabilities>
      <rescap:Capability Name="broadFileSystemAccess" />
    </Capabilities>

这些更改及其意图在 MSDN Magazine 的文章中详细讨论,标题为Universal Windows Platform - Closing UWP-Win32 Gaps。该文章指出:
如果您声明了任何受限制的功能,则会在提交应用程序包到商店进行发布时触发额外的审核。……如果您拥有此功能,则不需要 AppExecutionAlias。由于这是一个强大的功能,Microsoft 只会在应用程序开发人员提供充分的申请理由、说明如何使用以及如何使用户受益时才会授予该功能。
此外:
如果您声明了 broadFileSystemAccess 功能,则无需声明任何更具有针对性的文件系统功能(Documents、Pictures 或 Videos);事实上,应用程序不能同时声明 broadFileSystemAccess 和其他三个文件系统功能之一。
最后:
即使应用程序已被授予该功能,仍然存在运行时检查,因为这对用户构成隐私问题。就像其他隐私问题一样,应用程序将在第一次使用时触发用户同意提示。如果用户选择拒绝权限,则应用程序必须对此具有弹性。

3
我认为你可以让用户选择一次文件夹,并将其放入“FutureAccessList”中,以便以后始终可以访问它... - Rico Suter
2
文档库实际上是无法访问的,对吗?我想它在Windows 10中被删除了。 - user3911053
2
有没有办法黑进去?模拟用户选择器?将磁盘分配为可移动存储器?从库中访问它?我想从我的应用程序中访问我的树莓派上的所有文件...这太疯狂了,我竟然不能做到这一点... - user007
1
@user007:希望没有绕过这个的方法,因为这将是一个重大的安全问题... - Rico Suter
1
@JamesM,对于传统桌面应用程序来说,这确实是一个安全问题。你怎么会认为对所有文件(用户可以访问的文件)的不受限制的访问不构成安全风险呢?然而,传统桌面应用程序没有这种机制,因为在它们被引入的时候,安全性并不是一个重要的话题,并且它们没有添加限制,因为这基本上是不可能的,否则将破坏大多数现有软件。 - Stefan Fabian
显示剩余5条评论

5

被接受的答案不再完整。现在可以在应用程序清单中声明 broadFileSystemAccess 来任意读取文件系统。

文件访问权限 页面有详细信息。

请注意,用户仍然可以通过设置应用程序来撤销此权限。


1
你可以在VS 2017的UI中完成此操作。 点击清单文件 -> 功能 -> 选择照片库或其他所需功能。

enter image description here


0

这是一项受限制的功能。访问权限可以在设置 > 隐私 > 文件系统中进行配置,并启用您的应用程序的访问权限。由于用户可以随时在设置中授予或拒绝权限,因此您应确保您的应用程序对这些更改具有弹性。如果发现您的应用程序没有访问权限,您可以选择提示用户通过提供到Windows 10文件系统访问和隐私文章的链接来更改设置。请注意,用户必须关闭应用程序、切换设置并重新启动应用程序。如果他们在应用程序运行时切换设置,平台将暂停您的应用程序以便保存状态,然后强制终止应用程序以应用新的设置。在2018年4月更新中,权限的默认值为开启。在2018年10月更新中,默认值为关闭。

了解更多信息


0

这是不正确的: 使用文件扩展名关联或通过共享打开的文件 试一下,从邮件(Outlook)或桌面打开文件... 它根本不起作用 您首先必须通过文件选择器授予权限。 所以这是...


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接