1

I'm trying to set an env variable which I want it to be reachable from another windows shell (which is already opened) :

I have tried:

os.environ['start'] = 'test'

Then in a Windows cmd : env.exe | findstr 'start' returns nothing. Variable 'start' does not exist.

Then I tried:

subprocess.call(['setx.exe', 'start', 'test'])
SUCCESS: Specified value was saved

env.exe | findstr 'start' still returns nothing.

How can I get this variable from a windows shell ? Using Windows 10 and python 3. Thanks!

Eryk Sun
  • 33,190
  • 5
  • 92
  • 111
reasons
  • 23
  • 1
  • 6
  • Are you trying to get access to an environment variable set in a subprocess (hint, you cannot do this - see https://stackoverflow.com/questions/61755986/how-to-integrate-a-batch-script-that-sets-environment-variables-with-a-python-sc/61756263#61756263)? Or are you trying to pass environment variables to the subprocess? You question needs clarification. – Amitai Irron May 12 '20 at 16:57
  • 1
    setx.exe updates the environment in the registry and broadcasts a `WM_SETTINGCHANGE` "Environment" message to top-level windows. This includes the Windows shell, Explorer, which reloads its environment from the registry. It does not include console applications such as cmd.exe, which do not create or own any top-level windows. – Eryk Sun May 12 '20 at 22:20

1 Answers1

2

You have to call the Windows SETX from your python code in order to make your environment value saved from your code

os.system("SETX {0} {1} /M".format("start", "test"))

should do the trick. Dont forget to run your script as Administrator. In order for your command prompt to see the changes, make sure you close it and open a new command prompt, then try to find your environment value using env.exe

sergenp
  • 510
  • 4
  • 13
  • 2
    Setting a per-user variable with setx.exe would be fine, and not require running as an administrator. But this is all a waste of time since it cannot do what the question wants in terms of updating the environment of an existing instance of the cmd.exe. The only way to do that from outside of the target process would require unreliable code that makes use of undocumented process data structures in order to remotely modify the environment block of another process. – Eryk Sun May 12 '20 at 22:28
  • Thanks, but calling *os.getenv('start')* right after your *os.system()* command does not show anything (type is None), how do you explain that? – reasons May 13 '20 at 06:42
  • `SETX` updates the Environment key in Windows, not in the subprocess. If you want to get the Environment key both in subprocess and save it in the windows, you can basically modify code into this: ```os.environ['start'] = 'test' os.system("SETX {0} {1} /M".format("start", "test")) ``` Or simply restart your subprocess(your python code). See @Eryk Sun's comments – sergenp May 13 '20 at 07:21
  • 2
    The OP wants the variable to "be reachable from another windows shell (which is *already opened*)", as in an already running instance of cmd.exe. Even if one can modify the OS environment block of another process, which would be unreliable across different versions of Windows since there's no public API for this, there's still no guarantee that the shell isn't working from a private copy of the environment. That's why I called this a waste of time. OTOH, it could be paired with a batch script to be run in the existing shell that reloads the environment from the registry. – Eryk Sun May 13 '20 at 07:41