开发者

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 to putenv().

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.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜