Why such theoretically crossplatform code does not change Enviromental variable on Windows?
So I try next code:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <boost/filesystem/v3/path.hpp>
#include <boost/filesystem/v3/operations.hpp>
#ifdef WIN
#include <Windows.h>
#endif
void setEnviromentVariable(std::string name, boost::filesystem::path value)
{
if ( getenv (name.c_str())==NULL)
{
std::cout << "Hit ENTER to restart application in order to agree with the next terms of use: do not eat my bytes!)" << std::endl;
std::stringstream VAR;
VAR << name<< "=" << value.native().c_str();
#ifdef WIN
std::stringstream VAL;
VAL << value.native().c_str();
if( !SetEnvironmentVariable(TEXT(name.c_str()), TEXT(VAL.str().c_str())))
{
printf("SetEnvironmentVariable failed (%d)\n", GetLastError());
}
#else
setenv(VAR.str().c_str());
#endif
std::cin.get();
}
}
int main(int argc, char *argv[])
{
boost::filesystem::path full_path( boost::filesystem::current_path() / "assets/" );
setEnviromentVariable("TCL_LIBRARY", full_path);
}
What is wrong with my code? Why it does not set up any enviroment variable, and why it does not show me any errors? (WIN code is base开发者_如何学Pythond on this.)
putenv()
places the specified string pointer in the environment vector; it does not copy the string value.
The string pointed to by
string becomes
part of the environment. A program should not alter or free the string, and should not use stack or other transient string variables as arguments toputenv()
.
So when VAR
goes out of scope, the environment contains a garbage pointer and attempting to access it will segfault or return garbage.
In addition to geekosaur answer. If you run program from shell then you can, for example, write from your C++ program a string like "export TCL_LIBRARY=calculated_value" (depends on what shell do you use) to some file and then execute this file.
#!/bin/bash
your_program.exe
source generated_file_with_variable
next_program.exe
Your process has its own copy of the environment, and all your changes affect that copy. The only other programs that will see your modifications are child processes you start, and they will see your environment frozen in time when you spawn the child process. The program that started yours will be completely unaffected.
Because of this, your comment about restarting the application makes no sense. The new instance will get a copy of the parent process's environment, not the one you have been making changes to. (OTOH, if your program started the new copy, it would inherit your changed environment block.)
精彩评论