Revamped environment variables again.
A previous commit changed how environment variables were managed.
Initially we were calling SetEnvironmentVariable() on each variable
defined in AppEnvironmentExtra prior to starting the service. That
behaviour was changed because it was technically incorrect, potentially
resulting in NSSM's own environment being harmed.
Unfortunately the changed method, creating a new environment block by
calling GetEnvironmentStrings() (or using the block from AppEnvironment
if that and AppEnvironmentExtra were both defined), failed if users did
something like set AppEnvironmentExtra to PATH=C:\bin;%PATH%. That
would result in the process being started with a block which included
TWO occurrences of the PATH variable; the system-defined one and the
appended one. The latter would be ignored, possibly causing the
application to fail to start.
For this third attempt we now call GetEnvironmentStrings() once at
startup, storing the block in a new variable which is only freed at
exit. Immediately prior to calling CreateProcess() to start the service
we use the new environment functions duplicate_environment() (on
AppEnvironment) and set_environment_block() (on AppEnvironmentExtra) to
set the variables. Then immediately after calling CreateProcess() we
call duplicate_environment() again to restore the original block.
Because they are passed to expand_environment_string(), the environment
blocks are subject to expansion. That means that setting PATH as
described in the example above would work. Trying to append items to
the PATH by setting AppEnvironment in a similar way will probably not
work.
Thanks Bryan Senseman.