System Environment updaten



  • Heyho liebe Leute,

    ich habe gerade ein kleines Problem... Die Situation ist folgende:

    Ich habe eine Konsolenanwendung, in der ich irgendwann mittels Manipulation der Windows Registry neue System Environments anlege, in etwa so:

    // [...]
    HKEY keyConfig;
    std::string strVarName = "Varname";
    std::string strVarValue = "Varvalue";
    
    if(ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &keyConfig))
    // [...] Log-Output, etc...
    
    if(ERROR_SUCCESS != RegSetValueExA(keyConfig, strVarName.c_str(), 0, REG_SZ, (const BYTE*)strVarValue.c_str(), strVarValue.size()))
    // [...] Log-Output, etc...
    
    RegCloseKey(keyConfig);
    // [...]
    

    Klappt soweit.

    Jetzt möchte ich aber die eben hinzugefügten Environments im späteren Verlauf des Programms verwenden - das Problem ist nur, dass der aktuellen Console-Session die neuen Environments nicht bekannt sind 😞

    Ich kenn mich mit der WinAPI hier leider zu wenig aus, habe aber probiert eine Message (WM_SETTINGCHANGE) an alle Top-Level-Windows zu senden, wie folgt:

    PDWORD_PTR pdwResult = NULL;
    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, pdwResult);
    

    Klappt aber auch nicht 😕
    Hat jemand eine Idee? Wäre super 🙂

    Gruß
    PuerNoctis


  • Mod

    Environment Parameter werden beim Start des Prozesses kopiert und werden nicht mehr dynamisch ausgelesen. Der entsprechende Prozess müsste also neu starten.



  • Alles klar - danke für die Info 🙂

    Ein ziemlich identisches Problem gab es übrigens bereits hier im Forum (http://www.c-plusplus.net/forum/viewtopic-var-p-is-94503.html)

    Meine (funktionierende) Lösung ist momentan diese:

    Der obige Code blieb erstmal weiterhin bestehen, nur habe ich eine Zeile hinzugefügt:

    SetEnvironmentVariableA(strVarName.c_str(), strVarValue.c_str());
    /*
    -- Alternativ 'SetEnvironmentVariable' (ohne 'A' am Ende), für Unicode-Variante
    */
    

    Die Funktion setzt ein Environment für den laufenden Prozess, ohne die System-Environments direkt zu beeinflussen.

    Vorher hatte ich probiert, mit dem Shell-Command 'SET' das Environment zu setzen, was aber (bei mir) nicht funktioniert hat:

    system(std::string("SET " + strVarName + "=" + strVarValue).c_str());
    

    Mein Fazit, falls jemand System-Environments hinzufügen und verwenden will, ohne den Prozess neu starten zu müssen:

    //[...]
    /*
     *      System-Variablen in Windows setzen (dauerhaft)
     */ 
    HKEY keyConfig;
    std::string strVarName = "Varname";
    std::string strVarValue = "Varvalue";
    
    if(ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &keyConfig))
    // [...] Log-Output, etc...
    
    if(ERROR_SUCCESS != RegSetValueExA(keyConfig, strVarName.c_str(), 0, REG_SZ, (const BYTE*)strVarValue.c_str(), strVarValue.size()))
    // [...] Log-Output, etc...
    
    RegCloseKey(keyConfig);
    
    /*
     *      Sicherheitshalber eine Message an andere Windows senden
     */
    PDWORD_PTR pdwResult = NULL;
    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, pdwResult);
    
    /*
     *      Variable nochmal für den momentanen Prozess senden (flüchtig)
     */
    SetEnvironmentVariableA(strVarName.c_str(), strVarValue.c_str());
    //[...]
    

    Anmerkungen oder Bedenken zu der Variante sind selbstverständlich erwünscht 🙂

    Gruß
    PuerNoctis


  • Mod

    SetEnvironmentVariable hat keine Wirkung auf den aktuellen Prozess wenn dieser die CRT Funktion getenv benutzt.


Anmelden zum Antworten