www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Windows - std.process - Setting env variables from D

reply "wobbles" <grogan.colin gmail.com> writes:
I'm trying to set environment variables that will be visible when 
my D program exits.
It is possible in a windows batch file using the set command 
(like set "VAR=VALUE" )

However, running this in D using:

import std.process;
import std.stdio;

void main(){

auto pid1 = spawnShell(`set "VAR=VALUE"`);
pid1.wait();
auto pid2 = spawnShell(`set`);
pid2.wait();
}


however, upon exit, there is no VAR=VALUE in the environment.

Using std.process.environment["VAR"]= "VALUE"; doesnt store the 
variable in the parent either.

Any solutions that people know of?
Mar 30 2015
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Monday, 30 March 2015 at 12:28:19 UTC, wobbles wrote:
 Any solutions that people know of?
You can't from an exe, it is a limitation of the operating system (same on Linux btw, environment variable inheritance is always from parent to child, never from child to parent). The reason batch files can do it is that they don't run in a separate process, they just run a batch of commands inside the shell itself. https://msdn.microsoft.com/en-us/library/windows/desktop/ms682009%28v=vs.85%29.aspx "Altering the environment variables of a child process during process creation is the only way one process can directly change the environment variables of another process. A process can never directly change the environment variables of another process that is not a child of that process." If you're an administrator, you could poke the system-wide variables in the registry and tell the processes to reload them: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653%28v=vs.85%29.aspx but of course, changing system-wide registry entries affects way more than just your parent shell! If you need to change a parent shell variable, the only way is to do it from a batch file. You could perhaps run a .bat which sets the variable and calls your exe to help it do some work.
Mar 30 2015
parent reply "wobbles" <grogan.colin gmail.com> writes:
On Monday, 30 March 2015 at 12:54:28 UTC, Adam D. Ruppe wrote:
 On Monday, 30 March 2015 at 12:28:19 UTC, wobbles wrote:
 Any solutions that people know of?
You can't from an exe, it is a limitation of the operating system (same on Linux btw, environment variable inheritance is always from parent to child, never from child to parent). The reason batch files can do it is that they don't run in a separate process, they just run a batch of commands inside the shell itself. https://msdn.microsoft.com/en-us/library/windows/desktop/ms682009%28v=vs.85%29.aspx "Altering the environment variables of a child process during process creation is the only way one process can directly change the environment variables of another process. A process can never directly change the environment variables of another process that is not a child of that process." If you're an administrator, you could poke the system-wide variables in the registry and tell the processes to reload them: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653%28v=vs.85%29.aspx but of course, changing system-wide registry entries affects way more than just your parent shell! If you need to change a parent shell variable, the only way is to do it from a batch file. You could perhaps run a .bat which sets the variable and calls your exe to help it do some work.
Thanks Adam, Yeah, I knew it was the case in Linux, I just figured as 'set' worked in a batch file that it must be possible in Windows. I think what I'm going to do is have my D program output the commands as strings that are required to set the ENV variables in the parent and then have a batch file to run the program, get its output and run the commands outputted from the D program. Can also have a bash file to do the same (using the source command). This is for setting up a build system we're using, and is normally run via Jenkins, so running it in a kind of ugly way doesnt really matter. We're currently maintaining two seperate scripts to do this work, I'm trying to consolidate them. Maintaining one large-ish D script to do this work and 2 mini scripts to call them should be easier to maintain than 2 large bash/batch scripts. Thanks!
Mar 30 2015
parent reply "Laeeth Isharc" <Laeeth.nospam nospam-laeeth.com> writes:
On Monday, 30 March 2015 at 13:29:06 UTC, wobbles wrote:
 On Monday, 30 March 2015 at 12:54:28 UTC, Adam D. Ruppe wrote:
 On Monday, 30 March 2015 at 12:28:19 UTC, wobbles wrote:
 Any solutions that people know of?
You can't from an exe, it is a limitation of the operating system (same on Linux btw, environment variable inheritance is always from parent to child, never from child to parent). The reason batch files can do it is that they don't run in a separate process, they just run a batch of commands inside the shell itself. https://msdn.microsoft.com/en-us/library/windows/desktop/ms682009%28v=vs.85%29.aspx "Altering the environment variables of a child process during process creation is the only way one process can directly change the environment variables of another process. A process can never directly change the environment variables of another process that is not a child of that process." If you're an administrator, you could poke the system-wide variables in the registry and tell the processes to reload them: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653%28v=vs.85%29.aspx but of course, changing system-wide registry entries affects way more than just your parent shell! If you need to change a parent shell variable, the only way is to do it from a batch file. You could perhaps run a .bat which sets the variable and calls your exe to help it do some work.
Thanks Adam, Yeah, I knew it was the case in Linux, I just figured as 'set' worked in a batch file that it must be possible in Windows. I think what I'm going to do is have my D program output the commands as strings that are required to set the ENV variables in the parent and then have a batch file to run the program, get its output and run the commands outputted from the D program. Can also have a bash file to do the same (using the source command). This is for setting up a build system we're using, and is normally run via Jenkins, so running it in a kind of ugly way doesnt really matter. We're currently maintaining two seperate scripts to do this work, I'm trying to consolidate them. Maintaining one large-ish D script to do this work and 2 mini scripts to call them should be easier to maintain than 2 large bash/batch scripts. Thanks!
You tried setx, and it didn't work ? Or you don't want to set permanent environmental variables ?
Mar 30 2015
parent reply "wobbles " <grogan.colin gmail.com> writes:
On Monday, 30 March 2015 at 14:14:50 UTC, Laeeth Isharc wrote:
 On Monday, 30 March 2015 at 13:29:06 UTC, wobbles wrote:
 On Monday, 30 March 2015 at 12:54:28 UTC, Adam D. Ruppe wrote:
 On Monday, 30 March 2015 at 12:28:19 UTC, wobbles wrote:
 Any solutions that people know of?
You can't from an exe, it is a limitation of the operating system (same on Linux btw, environment variable inheritance is always from parent to child, never from child to parent). The reason batch files can do it is that they don't run in a separate process, they just run a batch of commands inside the shell itself. https://msdn.microsoft.com/en-us/library/windows/desktop/ms682009%28v=vs.85%29.aspx "Altering the environment variables of a child process during process creation is the only way one process can directly change the environment variables of another process. A process can never directly change the environment variables of another process that is not a child of that process." If you're an administrator, you could poke the system-wide variables in the registry and tell the processes to reload them: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653%28v=vs.85%29.aspx but of course, changing system-wide registry entries affects way more than just your parent shell! If you need to change a parent shell variable, the only way is to do it from a batch file. You could perhaps run a .bat which sets the variable and calls your exe to help it do some work.
Thanks Adam, Yeah, I knew it was the case in Linux, I just figured as 'set' worked in a batch file that it must be possible in Windows. I think what I'm going to do is have my D program output the commands as strings that are required to set the ENV variables in the parent and then have a batch file to run the program, get its output and run the commands outputted from the D program. Can also have a bash file to do the same (using the source command). This is for setting up a build system we're using, and is normally run via Jenkins, so running it in a kind of ugly way doesnt really matter. We're currently maintaining two seperate scripts to do this work, I'm trying to consolidate them. Maintaining one large-ish D script to do this work and 2 mini scripts to call them should be easier to maintain than 2 large bash/batch scripts. Thanks!
You tried setx, and it didn't work ? Or you don't want to set permanent environmental variables
Yep, correct. Don't want them to be permanent. The systems have to be clean for other tests at all times, so they need to be on a shell by shell basis sadly.
Mar 30 2015
parent "Laeeth Isharc" <nospamlaeeth nospam.laeeth.com> writes:
 You tried setx, and it didn't work ?  Or you don't want to set 
 permanent environmental variables
Yep, correct. Don't want them to be permanent. The systems have to be clean for other tests at all times, so they need to be on a shell by shell basis sadly.
Thanks - was curious to know. Laeeth.
Mar 30 2015
prev sibling parent "Laeeth Isharc" <nospamlaeeth nospam.laeeth.com> writes:
On Monday, 30 March 2015 at 12:28:19 UTC, wobbles wrote:
 I'm trying to set environment variables that will be visible 
 when my D program exits.
 It is possible in a windows batch file using the set command 
 (like set "VAR=VALUE" )

 However, running this in D using:

 import std.process;
 import std.stdio;

 void main(){

 auto pid1 = spawnShell(`set "VAR=VALUE"`);
 pid1.wait();
 auto pid2 = spawnShell(`set`);
 pid2.wait();
 }


 however, upon exit, there is no VAR=VALUE in the environment.

 Using std.process.environment["VAR"]= "VALUE"; doesnt store the 
 variable in the parent either.

 Any solutions that people know of?
Type setx /? in the command shell. (Note the x). http://stackoverflow.com/questions/5898131/set-a-persistent-environment-variable-from-cmd-exe
Mar 30 2015