【问题标题】:UWP C# and Windows Runtime Component C++ Permission Denied error when opening file打开文件时出现 UWP C# 和 Windows 运行时组件 C++ 权限被拒绝错误
【发布时间】:2021-04-04 07:59:33
【问题描述】:

我用 C# 开发了一个 UWP 应用,其中包含一个 Windows 运行时组件 C++ 项目。该应用程序允许用户选择一个 mp4 文件并将此文件传递给 c++ 代码,然后利用 ffmpeg 库检索视频文件的演示时间戳并将其输出到文件中。

我面临的问题是使用avformat_open_input函数时c++代码无法打开mp4文件:

int PTSExtraction::parse_file(Platform::String^ filename)
{
    int ret = 0;
    AVPacket pkt = { 0 };


    std::wstring fileNameW(filename->Begin());
    std::string fileNameA(fileNameW.begin(), fileNameW.end());
    const wchar_t* w_chars = fileNameW.c_str();
    src_filename = fileNameA.c_str(); 

    if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
        fprintf(stderr, "Could not open source file %s\n", src_filename);
        return 1; 
    }
    // rest of code 
}

avformat_open_input 收到的错误是Permission Denied。我什至无法通过以下方式在此函数中打开随机文本文件:

ofstream output; 
output.open("output.txt");

我意识到有文件系统权限阻止我的 uwp 应用程序的 C++ 组件打开文件。以下是我迄今为止尝试过的事情:

这些都不允许 C++ 组件打开任何文件。如果有人能解决这个问题,我将不胜感激。

【问题讨论】:

    标签: c# c++ ffmpeg uwp windows-runtime


    【解决方案1】:

    broadFileSystemAccess 功能可让您访问完整的文件系统,但并非针对所有 API,仅针对 UWP 的 Windows.Storage API。这意味着您必须使用StorageFolderStorageFile 才能访问该文件。例如,您可以使用StorageFile.GetFileFromPathAsync 检索文件from a given path

    【讨论】:

    • 我在从 C++ Windows 运行时组件打开文件时遇到问题,而不是从 UWP。
    • 没关系,C++ Windows 运行时组件可以完全访问 UWP API 集。请参阅@YanGu - MSFT 的答案
    【解决方案2】:

    Windows Runtime Componnet C++ 项目是一个Universal Windows 项目(UWP 项目)。您可以在 Solution Explorer 中的组件项目名称左侧看到字符 (Universal Windows)

    对于 UWP 项目(包括 Windows Runtime Componnet C++ 项目),您可以默认访问某些文件系统位置,例如应用程序安装目录、应用程序数据位置、用户下载文件夹,或 access libraries declaring capabilities,或让用户通过calling a file picker 选择文件和文件夹,参考File access permissions 文档。如果需要使用 StorageFile 对象读写文件,可以参考document

    例如,如果您的 mp4 文件在 Videos 库中,您可以使用以下代码获取文件:

    1. 在 C# UWP 项目的清单中添加 视频 功能。
    2. 作为示例检查代码:
    #include <winrt/Windows.Storage.h>
    #include <winrt/Windows.Storage.Search.h>
    
    using namespace winrt::Windows::Storage;
    using namespace winrt::Windows::Storage::Search;
    
    ……
    auto lib =co_await Windows::Storage::StorageLibrary::GetLibraryAsync(Windows::Storage::KnownLibraryId::Videos);
    auto folder = lib.Folders().GetAt(0);
    StorageFile myMp4 =co_await folder.GetFileAsync(L"test.mp4");
    
    

    如果您需要其他方式的C++代码,如访问默认位置或调用pickers访问文件,请随时与我联系。

    【讨论】:

      【解决方案3】:

      这不是因为您从用户那里选择的文件。 由于以下 2 种情况,可能会发生此错误

      1. 由于 FFmpeg Api 使用 Syncronus 文件访问系统和 uwp 不支持在除了应用程序本地目录的文件系统中,因此您可以通过首先将用户选择的文件复制到本地文件夹然后使用复制的文件来做到这一点访问文件。

      2. 由于在运行时访问 API 需要 dll,因此您必须将所有 Dll 添加到您拥有 App.xaml 的主文件夹中,然后将属性设置为内容并始终复制到所有 dll

      即avcodec、avdevice、avfilter、avformat、avresample、avutil、postproc、swresample、swscale

      阅读:“Windows 应用商店认证、文件 I/O 和其他详细信息”-http://trac.ffmpeg.org/wiki/CompilationGuide/WinRT

      【讨论】:

        猜你喜欢
        • 2017-04-11
        • 1970-01-01
        • 2014-05-08
        • 1970-01-01
        • 2013-01-29
        • 2021-07-12
        • 2017-11-14
        • 2017-03-06
        相关资源
        最近更新 更多