私の目標は、ディレクトリをPATH環境変数の既存の値に追加するコードを記述し、プログラムの継続時間の間PATH環境変数を新しい値に設定して、DLLを新しいディレクトリから読み込むことができるようにすることです。パス上の以前のディレクトリから削除します。コードはWindows上で実行するだけで、Visual C++ 2013と2015でコンパイルする必要があります。(理想的には、MinGWでもコンパイルできるようにしたいと思いますが、/ DELAYLOADと同等のものがないという事実は、 )。VC++ 2013でPATH環境変数を変更するサイレントエラーをどのように克服できますか?
実験後、SetEnvironmentVariable [W]はPATHの値を静かに変更することができませんが、_putenv、_putenv_s、_wputenv、および_wputenv_sは正しく動作しますが、VC++ 2015 VC++ 2013では、静かに失敗し、PATHの値は変更されません(VC++ 2013ではSetEnvironmentVariableが静かに失敗するのと同じ方法です)。私はインターネット上で検索したところで、この動作に言及していません。
SetEnvironmentVariableではなく_putenvを使うことができますが、VS2015で動作する方法とは異なる場合でも、VS2013でPATHの値を動的に変更する方法を理解する必要があります。
UPDATE:
ここで(それが呼び出すと、getPathFromEnvVarW()
)prependDirToEnvVarW()
です。 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;
}
}
何かがあれば、SetEnvironmentVariableは動作するはずです。 [mcve]を投稿する必要があるかもしれません。一方、DLLは通常、明示的なパスを使用してロードする必要があり、これにより問題が完全に回避されます。 –
Windows環境ではなく、 '_putenv'がC環境にのみ影響を与えるのは通常の(またはIIRCである)ことに注意してください。したがって、現在掲載されているコードは失敗する可能性があります。しかし、それが変更されていないと結論づけるPATHであなたが何をしているのかがわかりません。コードのその部分も投稿できますか? –