我的目标是编写将目录添加到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;
}
}
答案 0 :(得分:3)
前提是不正确的。 PATH
是搜索DLL的 last 事物。
相反,您应该致电SetDllDirectory()或AddDllDirectory()。这将设置DLL搜索路径,以便在可执行目录之后立即搜索添加的路径 second 。
如果您需要更精细的控制,则需要指定LoadLibrary()
函数的完整路径名。