如何在VC ++ 2013中克服静默失败以更改PATH环境变量?

时间:2017-10-03 03:35:47

标签: c++ windows environment-variables

我的目标是编写将目录添加到PATH环境变量的现有值的代码,并将PATH环境变量设置为程序持续时间的新值,以便也可以从新目录加载DLL。从之前在路径上的目录开始。代码只需要在Windows上运行,只需要使用Visual C ++ 2013和2015进行编译。(理想情况下,我希望能够使用MinGW进行编译,但事实上没有等同于/ DELAYLOAD意味着这可能是不可能的。)

我发现,在实验之后,SetEnvironmentVariable [W]无声地无法更改PATH的值,但_putenv,_putenv_s,_wputenv和_wputenv_s正常工作---但仅限于VC ++ 2015.在VC ++ 2013上,它们无声地失败,并保持PATH的值不变(与SetEnvironmentVariable在VC ++ 2013上静默失败的方式相同)。我在互联网上搜索过的任何地方都没有找到任何对此行为的引用。

我可以忍受使用_putenv而不是SetEnvironmentVariable,但我需要找到一种在VS2013中动态更改PATH值的方法,即使它与VS2015中的方式不同。

更新:

这是prependDirToEnvVarW()(以及它所调用的getPathFromEnvVarW())。 prependDirToEnvVarW()在VC ++ 2015上正常工作,但无法在VC ++ 2013上更改路径。

inline std::wstring getPathFromEnvVarW()
{
    DWORD bufferSize = GetEnvironmentVariableW(L"PATH", NULL, 0);
    std::wstring ret(bufferSize, wchar_t(0));
    DWORD getPathEnv = GetEnvironmentVariableW(L"PATH", &ret[0], bufferSize);
    return (getPathEnv ? ret : L"");
}

inline bool prependDirToEnvVarW(const std::wstring & wstrDir)
{
    const std::wstring PATH_VAR_NAME = L"PATH";
    std::wstring wstrPrevPath = getPathFromEnvVarW();
    std::wstring wstrValue = wstrDir;
    if (!wstrValue.empty() && wstrValue[wstrValue.length() - 1] != L';')
    {
        wstrValue += L";";
    }
    wstrValue += wstrPrevPath;

    std::replace(wstrValue.begin(), wstrValue.end(), L'/', L'\\');

    errno_t retVal = _wputenv_s(PATH_VAR_NAME.c_str(), wstrValue.c_str());
    std::cout << "Attempted to change PATH to:\n" << 
        std::string(wstrValue.cbegin(), wstrValue.cend()) << std::endl;
    if (retVal == 0)
    {
        return true;
    }
    else
    {
        std::cout << "retVal is nonzero: " << retVal 
            << " (compare to EINVAL == " << EINVAL << ")" << std::endl;
        return false;
    }
}

1 个答案:

答案 0 :(得分:3)

前提是不正确的。 PATH是搜索DLL的 last 事物。

相反,您应该致电SetDllDirectory()AddDllDirectory()。这将设置DLL搜索路径,以便在可执行目录之后立即搜索添加的路径 second

如果您需要更精细的控制,则需要指定LoadLibrary()函数的完整路径名。