从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 System
和Network 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'
。 如果它使用您的用户帐户,则可以访问您通常可以访问的所有环境变量。
。