在UWP中获取fopen()的应用程序路径

时间:2017-01-01 05:17:13

标签: c++ uwp

我正在将现有的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”。为什么不?它是应用程序的文件夹,不是吗?

1 个答案:

答案 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。