从Windows服务访问环境变量

我试图用C#编写Windows服务。 我需要找到某个文件的路径,该文件存储在环境变量中。 在常规的C#控制台应用程序中,我可以通过以下行实现:

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

如果我把它写到控制台,我发现它是成功的。

现在,如果我在Windows服务中尝试相同的代码,则字符串t为空。

知道为什么吗?

我不知道这是否有用,但我发现对于每个服务,都可以选择将环境变量直接添加到服务中。

它是通过注册表完成的。

说服务的关键是……

HKLM \系统\ CurrentControlSet \服务\ YourService

创建一个名为Environment的REG_MULTI_SZ。

现在你可以添加像……这样的条目

 Var1=Value1 Var2=Value2 

这些将可用于服务代码。

如果您使用Windows资源工具包将脚本作为服务安装(instsrv.exe和srvany.exe),那么,您可以选择为服务设置环境变量,但很可能是错误的,因为这些将用于srvany.exe。

相反,你使用密钥……

HKLM \系统\ CurrentControlSet \服务\ YourService \参数

并创建一个名为AppEnvironment的REG_MULTI_SZ

以相同的方式设置条目。

现在你的脚本服务有它自己的环境变量。

我在PHP + WinCache中使用这些技术,允许我为每个服务设置唯一的APP_POOL_ID,允许WinCache为所有“线程”共享中央缓存(基于APP_POOL_ID)(使用WShell启动非阻塞子线程) “并且仍然与启动器共享相同的WinCache,允许简单的进程间通信。

无论如何。 我希望这有点帮助。

我认为,总的来说,你没有在全球环境中添加不必要的env_vars。 当你有超过1时,你可以保持目标和独特。

问候,

理查德。

你的问题似乎就像我们经历的那样,并且可以非常难以弄清楚发生了什么。

发生的情况是添加/删除/更改环境变量时, 服务环境在“重新启动”之前无法识别。 这是因为这些环境变量存储在注册表中,并且此注册表系统启动时由服务环境读取一次

这意味着为了使服务能够获取环境变量的变化,需要进行系统重启。

在此查看Microsoft KB 。

该服务可能在不同的帐户下运行,并且没有获得相同的环境变量。

好吧,我不太明白这一点,但这是我发现的……

在同一个服务中,我首先尝试我之前描述的,字符串返回空。

然后,如果我枚举每个系统级环境变量,它会找到我正在寻找的变量。

这是一段代码片段,稍微修改了MSDN上的一些示例代码:

 foreach(DictionaryEntry de in Environment.GetEnvironmentVariables(tgt)) { key = (string)de.Key; value = (string)de.Value; if(key.Equals("TIP_HOME") && value != null) log.WriteEntry("TIP_HOME="+value, EventLogEntryType.Information); } 

您是否在本地系统帐户下运行该服务?

添加TIP_HOME变量后重启机器了吗?

在本地系统下运行的服务从services.exe服务启动,该服务仅在启动时读取其环境: http : //support.microsoft.com/kb/821761

试试这段代码字符串getsyspath = System.Environment.GetEnvironmentVariable(“TIP_HOME”,EnvironmentVariableTarget.Machine);

您需要检查变量的存储方式。 Set / GetEnvironmentVariable有重载方法:

Environment.GetEnvironmentVariable方法(String,EnvironmentVariableTarget)

问题是,存储环境变量有三种类型( EnvironmentVariableTarget ):

  • 机器(适用于所有用户)
  • 用户(适用于当前用户)
  • 流程(仅适用于当前流程[不推荐顺便说一句])

如果您将信息存储为计算机或用户,则可以将其测试为运行Run(Win + R):%TIP_HOME%

希望能帮助到你 :)

您是否了解系统用户环境变量? 默认情况下,Windows服务在系统帐户下运行。

我修改了这行代码:

string t = System.Environment.GetEnvironmentVariable(“TIP_HOME”,EnvironmentVariableTarget.Machine);

我可以通过我的注册表查看TIP_HOME已设置。

这来自MSDN:Machine:环境变量是从Windows操作系统注册表中的HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment键存储或检索的。

用户变量存储在注册表的其他位置。

但是,当我使用此更改运行服务时,字符串仍然显示为空。

服务通常在三个服务帐户之一, Local Service Local SystemNetwork Service 。 对于所有这些,您的典型环境变量将为null


去弄清楚


我通过让服务编写一个事件日志条目进行测试,并打印它存储在HOMEPATH变量中的内容。 它为服务帐户返回空。 在C#中:

 protected override void OnStart(string[] args) { EventLog.WriteEntry("The HomePath for this service is '" + Environment.GetEnvironmentVariable("HOMEPATH") + "'", EventLogEntryType.Information); } 

可能的解决方案


您可以在服务属性窗口或服务安assembly置中设置服务使用的帐户(例如,您的用户帐户)。 当我使用我的用户帐户测试时,显示的事件日志条目The HomePath for this service is '\Users\Admin-PC' 。 如果它使用您的用户帐户,则可以访问您通常可以访问的所有环境变量。
在此处输入图像描述在此处输入图像描述