【问题标题】:UWP/WinRT: When calling CachedFileManger::DeferUpdates, getting Access Denied on files in Dropbox folderUWP/WinRT:调用 CachedFileManger::DeferUpdates 时,对 Dropbox 文件夹中的文件拒绝访问
【发布时间】:2015-11-10 09:37:18
【问题描述】:

我有一个可以保存文件的通用 Windows 平台应用。在大多数情况下,它工作得很好。但是,每当我尝试将文件保存到 Dropbox 监视的文件夹中时,都会出现以下异常:

Platform::AccessDeniedException ^ 在内存位置 0x045FD0D0。 HRESULT:0x80070005 访问被拒绝。 WinRT 信息:访问被拒绝。

这是由我的代码中的这一行引起的,在我保存文件之前调用:

CachedFileManager::DeferUpdates(file);

documentation 中的任何内容都没有向我表明问题所在,或者实际上甚至可能引发此异常,尽管在大多数 API 中当然没有详细记录异常。

OneDrive 监视的文件夹中不会出现此问题。

文件是否已同步到 Dropbox 似乎并不重要。如果文件是新文件,则将创建一个新文件,然后抛出此异常。如果文件存在,则在更新之前会抛出此异常。

为什么会发生这种情况,我该如何正确解决?

现在,我只是将该行包含在一个 try catch 块中,我丢弃了AccessDeniedException

更新:我刚刚切换到 Windows Insider 预览版。我在 Build 14295 上,这个问题略有变化。这是新的例外:

Platform::COMException ^ 在内存位置 0x00000043892FB9F0。 HRESULT:0x8000FFFF 灾难性故障

仍然不知道为什么会发生这种情况,但类似的黑客解决方案有效,现在我也丢弃了COMException

【问题讨论】:

    标签: windows-runtime win-universal-app c++-cx


    【解决方案1】:

    这意味着您无权通过 Winrt 代码在该位置保存文件。就文件 IO 权限而言,它被锁定得非常严密。听起来您不是使用 FileSavePicker 来保存文件,而是您自己创建文件存储对象并手动指定文件路径位置?

    如果您使用 FileSavePicker,它将返回一个 stroagefile 对象,该对象具有您在用户选择的任何位置保存文件所需的所有权限。

                    FileSavePicker savePicker = new FileSavePicker();
                    savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
                    // Dropdown of file types the user can save the file as
                    savePicker.FileTypeChoices.Add(this.loadedFile.FileType.Substring(1), new List<string>() { this.loadedFile.FileType });
                    // Default extension if the user does not select a choice explicitly from the dropdown
                    savePicker.DefaultFileExtension = this.loadedFile.FileType;
                    // Default file name if the user does not type one in or select a file to replace
                    savePicker.SuggestedFileName = file.Name.Trim();
                    //savePicker.view
                    StorageFile savedItem = await savePicker.PickSaveFileAsync();
    
                    if (savedItem != null)
                    {
                        CachedFileManager.DeferUpdates(savedItem);
                        await FileIO.WriteBytesAsync(savedItem, new byte[0]); //truncate current content in case it already exists
                        await FileIO.WriteBytesAsync(savedItem, buffer);
                        await CachedFileManager.CompleteUpdatesAsync(savedItem);                          
                    }
    

    【讨论】:

    • 不,即使使用 FileSavePicker 也会发生这种情况。 Dropbox 文件夹有一些特别之处。据我所知,我可以使用相同的代码并将文件保存在任何地方,包括驱动器上的根文件夹,但它会阻塞 Dropbox 文件夹中的任何内容。
    • 我已经构建了一个可以启动 fileSavePicker 的应用程序,因此我安装了 dropbox 以测试保存到 dropbox 文件夹。它对我来说很好用。您是否专门导航到 c:\Users[User]\Dropbox 进行保存?还是其他捷径?您是否尝试过 Dropbox 版本 3.8.8?
    • 您能否将文件保存到另一个临时位置,例如文档文件夹中,然后将其复制到用户从 Dropbox 文件夹中选择的 storageFile 对象?
    • 你在调用 DeferUpdates 吗?因为正是那个电话特别导致了我的异常。我的 Dropbox 文件夹位于 D:\Dropbox,我直接在那里导航。我刚刚将 Dropbox 更新到 3.8.8,问题仍然存在。除非我遗漏了某些东西,否则在其他地方创建文件然后复制它不会改变任何东西,因为问题调用是当我尝试在 Dropbox 文件夹树内的目标处延迟更新时。这是在我的任何代码实际将数据写入文件之前。
    • 在 await PickSaveFileAsync 调用之后,我修改了答案以包含一个 IF 块。它对我来说很好,我没有例外。 D:\Dropbox 文件夹有什么特殊权限吗?对我来说,SYSTEM、[用户] 和管理员对该特定文件夹拥有所有权限:完全控制、修改、读取和执行、列出文件夹内容、读取、写入
    猜你喜欢
    • 2013-08-28
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多