我正在将现有的C / C ++应用程序移植到使用fopen()/ fclose()的UWP。在Win32上,我曾经使用以下两个函数来获取应用程序资源的路径(只读),并获取应用程序存储的路径(读/写):
char resourcePath[2048];
const char *GetResourcePath(void)
{
GetCurrentDirectoryA(sizeof(resourcePath), resourcePath);
strcat(resourcePath, "/");
return resourcePath;
}
char storagePath[2048];
const char *GetStoragePath(void)
{
GetCurrentDirectoryA(sizeof(storagePath), storagePath);
strcat(storagePath, "/");
return storagePath;
}
UWP的等价物是什么?我似乎只能在C#中找到信息。 看来我可以从这个文件夹“rb”fopen()文件,但我不能“wb”。为什么不?它是应用程序的文件夹,不是吗?
答案 0 :(得分:0)
GetCurrentDirectory适用于UWP,但您必须使用Unicode变体(GetCurrentDirectoryW而不是GetCurrentDirectoryA)。但是,我不会使用它来获取安装应用程序的位置,因为可以使用SetCurrentDirectory轻松覆盖它。
您可以使用Package.InstalledLocation属性,然后在返回的StorageFolder上使用Path属性,但如果您使用该属性,则无法与Win32应用程序共享代码。
我建议做的是使用GetModuleFileNameW检索可执行文件的路径,然后修剪最后一个路径组件以获取目录:
#include <windows.h>
#include <string>
extern "C" IMAGE_DOS_HEADER __ImageBase;
std::wstring GetExecutablePath()
{
std::wstring buffer;
size_t nextBufferLength = MAX_PATH;
for (;;)
{
buffer.resize(nextBufferLength);
nextBufferLength *= 2;
SetLastError(ERROR_SUCCESS);
auto pathLength = GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase), &buffer[0], static_cast<DWORD>(buffer.length()));
if (pathLength == 0)
throw std::exception("GetModuleFileName failed"); // You can call GetLastError() to get more info here
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
buffer.resize(pathLength);
return buffer;
}
}
}
void RemoveLastPathComponent(std::wstring& path)
{
auto directoryLength = path.length() - 1;
while (directoryLength > 0 && path[directoryLength] != '\\' && path[directoryLength] != '/')
directoryLength--;
if (directoryLength > 0)
path.resize(directoryLength);
}
std::wstring GetExecutableDirectory()
{
auto executablePath = GetExecutablePath();
RemoveLastPathComponent(executablePath);
return executablePath;
}
另外值得注意的是:不要使用fopen。如果用户的用户名中包含非英文字符,且在当前代码页中无法表示,则代码将失败。改为使用_wfopen或CreateFile2。