Visual Studio C++ UWP应用文件写入失败及跨路径访问问题
问题描述
我正在用C++开发Universal Windows Platform(UWP)应用,需要实现文件创建与写入功能。发现只有把文件添加到解决方案并修改属性为“可引用文本文件”才能读取,但写入时这类文件无法正常工作。
以下两种测试代码在Visual Studio的C++ UWP应用中均提示“无法打开文件”,但在VS Code中单独运行完全正常:
使用fopen的代码
//_CRT_SECURE_NO_WARNINGS included in preprocessor #include <errno.h> #include <stdio.h> #include <string.h> void VMatrix::SaveFile(string _fileName) { FILE* filepoint; if ((filepoint = fopen("fileName.txt", "w")) == NULL) { // File could not be opened. filepoint was set to NULL // error code was stored in errno. // error message can be retrieved with strerror(err); fprintf(stderr, "cannot open file '%s': %s\n", "fileName.txt", strerror(errno)); } else { // File was opened, filepoint can be used to read the stream. fclose(filepoint); } }
使用fstream的代码
#include <string> #include <iostream> #include <fstream> void VMatrix::SaveFile(string _fileName) { fstream myfile; myfile.open("Test.txt", std::ios::out); if (!myfile.is_open()) { std::cerr << "*** error: could not open output file\n"; } myfile << "Test"; myfile.close(); }
我已经修复了程序工作目录的权限问题,但还是无法指定计算机其他路径进行文件读写,请问是否可以在项目中启用相关权限来解决?
原因分析
- UWP应用默认运行在沙箱环境中,只能访问系统分配的受限目录(比如应用安装目录、应用数据目录),标准C++文件API默认指向的路径不在沙箱允许范围内,直接用相对路径自然会失败。
- 应用安装目录是只读的,就算把文件添加到解决方案,也只能读取,根本没法写入。
解决方案
1. 配置应用权限(访问外部目录)
如果需要访问文档库、图片库这类系统目录,得先在项目的Package.appxmanifest里配置权限:
- 打开
Package.appxmanifest,切换到功能标签页 - 根据需求勾选对应权限,比如
文档库、图片库 - 要是需要访问任意文件路径,还得勾选
文件系统权限(注意:这个权限提交应用商店时需要额外审核)
2. 使用合法的文件路径
UWP有几个允许读写的默认目录,必须通过UWP原生API获取这些路径,再配合标准C++操作:
获取本地应用数据目录(可读写,仅当前应用可见)
#include <winrt/Windows.Storage.h> using namespace winrt; using namespace Windows::Storage; // 获取本地应用数据目录路径 StorageFolder localFolder = ApplicationData::Current().LocalFolder(); std::wstring localPath = localFolder.Path(); std::wstring filePath = localPath + L"\\Test.txt";
获取文档库路径(需先配置权限)
#include <winrt/Windows.Storage.h> using namespace winrt; using namespace Windows::Storage; // 获取文档库路径 StorageFolder documentsFolder = KnownFolders::DocumentsLibrary(); std::wstring docPath = documentsFolder.Path(); std::wstring filePath = docPath + L"\\Test.txt";
3. 适配标准C++文件操作
UWP的路径默认是宽字符格式,建议用宽字符版本的文件API避免编码问题:
- 用
_wfopen替代fopen - 用
std::wfstream替代std::fstream
示例:用_wfopen写入应用数据目录
//_CRT_SECURE_NO_WARNINGS included in preprocessor #include <errno.h> #include <stdio.h> #include <string.h> #include <winrt/Windows.Storage.h> using namespace winrt; using namespace Windows::Storage; void VMatrix::SaveFile(std::string _fileName) { // 转换文件名到宽字符 std::wstring wideFileName(_fileName.begin(), _fileName.end()); // 获取应用数据目录 StorageFolder localFolder = ApplicationData::Current().LocalFolder(); std::wstring localPath = localFolder.Path(); std::wstring filePath = localPath + L"\\" + wideFileName; FILE* filepoint; if ((filepoint = _wfopen(filePath.c_str(), L"w")) == NULL) { fprintf(stderr, "cannot open file '%ls': %s\n", filePath.c_str(), strerror(errno)); } else { fwprintf(filepoint, L"Test content"); fclose(filepoint); } }
4. 注意事项
- 应用安装目录是只读的,只能读取打包进去的资源文件,不能写入
- 绝对不要硬编码路径,必须通过UWP API获取合法路径,否则沙箱会拦截访问
- 如果坚持用多字节版本的API,需要在项目属性里把“字符集”设置为“使用多字节字符集”,但更推荐用宽字符适配UWP环境
内容的提问来源于stack exchange,提问作者Ryan Gowland
相关产品推荐
相关产品推荐

