Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Environment Variables from Windows Services

I am attempting to write a Windows Service in C#. I need to find the path to a certain file, which is stored in an environment variable. In a regular C# console application, I can achieve that with the following line:

string t = System.Environment.GetEnvironmentVariable("TIP_HOME"); 

If I write that to the console I see that it was successful.

Now, if I try that same code in a Windows Service, the string t is empty.

Any idea why?

like image 840
Brian Avatar asked Nov 20 '08 16:11

Brian


People also ask

How can I see environment variables in CMD?

On WindowsSelect Start > All Programs > Accessories > Command Prompt. In the command window that opens, enter set. A list of all the environment variables that are set is displayed in the command window.

Where are Windows environment variables stored?

Machine environment variables are stored or retrieved from the following registry location: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment . Process environment variables are generated dynamically every time a user logs in to the device and are restricted to a single process.


2 Answers

I've no idea if this is useful, but I've found that for every service, there is an option to add environment variables directly to a service.

It is done via the registry.

Say the key to your service is ...

HKLM\SYSTEM\CurrentControlSet\Services\YourService

Create a REG_MULTI_SZ called Environment.

Now you can add entries like ...

Var1=Value1 Var2=Value2 

and these will be available to the service code.

If you are using the Windows Resource ToolKit to install scripts as a service (instsrv.exe and srvany.exe), then, again, you have the option of setting Environment variables for the service, but most likely it is the wrong one as these would be for srvany.exe.

Instead, you use the key ...

HKLM\SYSTEM\CurrentControlSet\Services\YourService\Parameters

and create a REG_MULTI_SZ called AppEnvironment

Set the entries in the same way.

And now your script service has it's own environment variables.

I'm using these techniques with PHP+WinCache to allow me to set an APP_POOL_ID unique to each service which allows WinCache to share a central cache (based upon APP_POOL_ID) for all "threads" (using WShell to launch non-blocking child "threads" and still share the same WinCache as the launcher, allowing simplistic, inter-process communication).

Anyway. I hope this helps somewhat.

I think, in the main, you aren't adding unnecessary env_vars to the global environment. You can keep them targetted and unique when you have more than 1.

Regards,

Richard.

like image 128
Richard Quadling Avatar answered Sep 21 '22 21:09

Richard Quadling


Your problem seems to be something like we've experienced and can be very tricky to figure out what's going on.

What happens is when environment variables are added/removed/changed, the services environment does not recognize this until it "restarts". This is because these environment variables are stored in the registry and this registry is read only once by the service environment... at system startup.

This means that in order for a service to pickup a change in environment variables, a system restart needs to occur.

Check out the Microsoft KB on this.

like image 39
Scott Saad Avatar answered Sep 20 '22 21:09

Scott Saad