c# - 即使授予访问权限,在 UWP 中访问文件也会引发 UnauthorizedAccessException
问题描述
我正在尝试浏览文件并将它们发送到服务,为此我正在 UWP 中制作一个小型内部实用程序应用程序。
我制作了一个 POC 控制台应用程序,一切正常。
现在我在一个 UWP 应用程序中,我System.UnauthorizedAccessException
在执行相同的代码时得到一个。
我必须补充一点,异常来自我正在使用的包(但我没有开发),我假设因为它在控制台应用程序而不是 UWP 应用程序中工作,所以错误来自我的最终,仍然在这里是完整的错误信息:
An exception of type 'System.UnauthorizedAccessException' occurred in System.Private.CoreLib.dll but was not handled in user code
Access to the path 'D:\pulseinvoices\uk_00003.pdf' is denied.
我在清单中做了同样的事情:
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
...
<Capabilities>
<rescap:Capability Name="broadFileSystemAccess" />
<Capability Name="internetClient" />
<uap:Capability Name="documentsLibrary"/>
</Capabilities>
我在某处读过,将文件设置为环境变量也是必要的。这将完全违背文件选择的目的(如果用户每次需要选择文件时都需要设置环境变量,那是不切实际的),但是嘿,我愿意接受建议,所以我也这样做了:
为了尽可能完整,这是我正在执行的代码:
private static readonly string FILE = @"D:\pulseinvoices\uk_00003.pdf"; //Test document
await service.ProcessAndWait(FILE, channel, params);
我迷路了,因为控制台应用程序工作正常,执行此代码仅在 UWP 应用程序中失败。
重要:该service
对象来自外部 .dll,正如我在帖子前面所说的那样。我仍然希望这个问题来自我的最终,所以我可以解决它。所以我有使用的路径StorageFile
,但是当那个 .dll 试图访问它时,我得到了异常。该 .dll 在我的解决方案中,因此它应该具有与解决方案相同的访问权限,对吗?
一切都是硬编码的,在这个阶段这几乎是一个单行应用程序。唯一的区别是它在 UWP 和控制台中运行。
我有哪些选择?
编辑:为清楚起见,添加更多细节。
这是我在使用外部 .dll 处理文件之前首先获取文件的方法。
在 后面selectFile
,使用文件路径创建了一个自定义对象,因此我确实有一个StorageFile
可以在我的 UWP 应用程序中使用的对象。只有一次我使用该外部 .dll 并且file.Path
它失败了。如果我根本不使用存储文件而只是对路径进行硬编码,我也会遇到同样的异常。我的解决方案可以访问该文件,但该解决方案中的 .dll 不能?
解决方案
即使您声明了该broadFileSystemAccess
功能,您仍然无法通过非 UWP API 访问文件。相反,您必须使用StorageFile
API:
var file = await StorageFile.GetFileFromPathAsync(path);
如果要与非 UWP API 互操作,可以使用Stream
文件的 。添加using System.IO;
到文件顶部,然后阅读:
var stream = await storageFile.OpenStreamForReadAsync();
或者写:
var stream = await storageFile.OpenStreamForWriteAsync();