我正在尝试用C#编写Windows服务。我需要找到某个文件的路径,该文件存储在环境变量中。在常规的C#控制台应用程序中,我可以使用以下行来实现:
string t = System.Environment.GetEnvironmentVariable("TIP_HOME");
如果我把它写到控制台,我发现它是成功的。
现在,如果我在Windows服务中尝试相同的代码,则字符串t
为空。
知道为什么吗?
答案 0 :(得分:29)
我不知道这是否有用,但我发现对于每项服务,都可以选择将环境变量直接添加到服务中。
通过注册表完成。
说服务的关键是......
HKLM \系统\ CurrentControlSet \服务\ YourService
创建一个名为Environment的REG_MULTI_SZ。
现在您可以添加像......
这样的条目Var1=Value1
Var2=Value2
这些将可用于服务代码。
如果您使用Windows Resource ToolKit将脚本作为服务安装(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时,你可以保持目标和唯一。
此致
理查德。
答案 1 :(得分:18)
你的问题似乎与我们经历过的一样,并且可能非常难以弄清楚发生了什么。
当添加/删除/更改环境变量时,服务环境在“重新启动”之前无法识别此情况。这是因为这些环境变量存储在注册表中,并且此注册表由服务环境只读一次 ...在系统启动。
这意味着为了使服务能够获取环境变量的变化,需要重新启动系统。
查看Microsoft KB。
答案 2 :(得分:6)
该服务可能在不同的帐户下运行,并且没有获得相同的环境变量。
答案 3 :(得分:1)
好的,我不太明白这一点,但这是我发现的......
在同一个服务中,我首先尝试我之前描述的内容,字符串返回空。
然后,如果我枚举每个系统级环境变量,它会找到我正在寻找的变量。
以下是一段代码片段,稍微修改了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);
}
答案 4 :(得分:1)
您是否在本地系统帐户下运行该服务?
添加TIP_HOME变量后,您是否重新启动了计算机?
在本地系统下运行的服务从services.exe服务启动,该服务仅在启动时读取其环境:http://support.microsoft.com/kb/821761
答案 5 :(得分:1)
试试这段代码 string getsyspath = System.Environment.GetEnvironmentVariable(“TIP_HOME”,EnvironmentVariableTarget.Machine);
答案 6 :(得分:1)
您需要检查变量的存储方式。 有Set / GetEnvironmentVariable的重载方法:
Environment.GetEnvironmentVariable Method (String, EnvironmentVariableTarget)
问题是,存储环境变量有三种类型(EnvironmentVariableTarget):
如果您将信息存储为计算机或用户,则可以将其测试为正在运行的运行(Win + R):%TIP_HOME%
希望有所帮助:)
答案 7 :(得分:0)
您是否了解系统和用户环境变量?默认情况下,Windows服务在系统帐户下运行。
答案 8 :(得分:0)
我修改了这行代码:
string t = System.Environment.GetEnvironmentVariable(“TIP_HOME”,EnvironmentVariableTarget.Machine);
我可以查看我的注册表,看看TIP_HOME已设置。
这是来自MSDN: 计算机:从Windows操作系统注册表中的HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment键存储或检索环境变量。
用户变量存储在注册表的其他位置..
但是,当我使用此更改运行服务时,字符串仍然显示为空。
答案 9 :(得分:0)
服务通常在三个服务帐户之一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);
}
可能的解决方案
您可以在服务属性窗口或服务安装配置中设置服务使用的帐户(例如您的用户帐户)。当我使用我的用户帐户测试时,事件日志条目显示为The HomePath for this service is '\Users\Admin-PC'
。如果它使用您的用户帐户,则可以访问您通常可以访问的所有环境变量
。