Почему такой теоретически кроссплатформенный код не меняет переменную Enviromental в Windows? - PullRequest
0 голосов
/ 06 июля 2011

Поэтому я пробую следующий код:

#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);
}

Что не так с моим кодом?Почему он не устанавливает никакой переменной среды, и почему он не показывает мне никаких ошибок?( Код WIN основан на этом. )

Ответы [ 3 ]

2 голосов
/ 06 июля 2011

putenv() помещает указанный строковый указатель в вектор среды;строковое значение не копируется.

Строка, на которую указывает string becomes часть среды.Программа не должна изменять или освобождать строку и не должна использовать стек или другие временные строковые переменные в качестве аргументов для putenv().

Поэтому, когда VAR выходит из области видимости, среда содержитуказатель мусора и попытка доступа к нему приведет к ошибке или возврату мусора.

1 голос
/ 06 июля 2011

В дополнение к ответу geekosaur. Если вы запускаете программу из оболочки, вы можете, например, записать из вашей программы на C ++ строку типа «export TCL_LIBRARY = computing_value» (зависит от того, какую оболочку вы используете) в некоторый файл, а затем выполнить этот файл.

#!/bin/bash
your_program.exe
source generated_file_with_variable
next_program.exe
0 голосов
/ 06 июля 2011

У вашего процесса есть собственная копия среды, и все ваши изменения влияют на эту копию. Единственные другие программы, которые увидят ваши изменения - это дочерние процессы, которые вы запускаете, и они увидят, что ваше окружение застыло во времени, когда вы породите дочерний процесс. Программа, которая запустила вашу программу, останется без изменений.

Из-за этого ваш комментарий о перезапуске приложения не имеет смысла. Новый экземпляр получит копию среды родительского процесса, а не ту, в которую вы вносили изменения. (OTOH, если ваша программа запустит новую копию, она унаследует ваш измененный блок среды.)

...