我正在尝试用 C# 编写 Windows 服务。我需要找到某个文件的路径,该文件存储在环境变量中。在常规的 C# 控制台应用程序中,我可以使用以下行来实现:
string t = System.Environment.GetEnvironmentVariable("TIP_HOME");
如果我将其写入控制台,我会看到它是成功的。
现在,如果我在 Windows 服务中尝试相同的代码,则字符串t
为空。
知道为什么吗?
我正在尝试用 C# 编写 Windows 服务。我需要找到某个文件的路径,该文件存储在环境变量中。在常规的 C# 控制台应用程序中,我可以使用以下行来实现:
string t = System.Environment.GetEnvironmentVariable("TIP_HOME");
如果我将其写入控制台,我会看到它是成功的。
现在,如果我在 Windows 服务中尝试相同的代码,则字符串t
为空。
知道为什么吗?
我不知道这是否有用,但我发现对于每个服务,都可以选择将环境变量直接添加到服务中。
它是通过注册表完成的。
说您的服务的关键是...
HKLM\SYSTEM\CurrentControlSet\Services\YourService
创建一个名为 Environment 的 REG_MULTI_SZ。
现在您可以添加条目,例如...
Var1=Value1
Var2=Value2
这些将可用于服务代码。
如果您使用 Windows 资源工具包将脚本安装为服务(instsrv.exe 和 srvany.exe),那么您可以再次选择为服务设置环境变量,但很可能是错误的,因为这些将用于 srvany.exe。
相反,您使用密钥...
HKLM\SYSTEM\CurrentControlSet\Services\YourService\Parameters
并创建一个名为 AppEnvironment 的 REG_MULTI_SZ
以相同的方式设置条目。
现在您的脚本服务拥有自己的环境变量。
我将这些技术与 PHP+WinCache 一起使用,以允许我为每个服务设置唯一的 APP_POOL_ID,这允许 WinCache 为所有“线程”(使用 WShell 启动非阻塞子“线程”共享中央缓存(基于 APP_POOL_ID) "并且仍然与启动器共享相同的 WinCache,允许简单的进程间通信)。
反正。我希望这会有所帮助。
我认为,主要是,您不会向全局环境添加不必要的 env_vars。当您拥有超过 1 个时,您可以使它们具有针对性和独特性。
问候,
理查德。
您的问题似乎与我们经历过的类似,并且很难弄清楚发生了什么。
发生的情况是,当环境变量被添加/删除/更改时,服务环境在“重新启动”之前不会识别这一点。这是因为这些环境变量存储在注册表中,并且该注册表仅被服务环境读取一次......在系统启动时。
这意味着为了让服务获取环境变量的变化,需要重新启动系统。
查看有关此的Microsoft KB。
该服务可能在不同的帐户下运行,并且没有获得相同的环境变量。
您是否在本地系统帐户下运行该服务?
添加 TIP_HOME 变量后是否重新启动了机器?
在本地系统下运行的服务从 services.exe 服务启动,该服务仅在启动时读取其环境:http: //support.microsoft.com/kb/821761
您知道系统和用户环境变量吗?默认情况下,Windows 服务在系统帐户下运行。
好的,我不太明白这一点,但这是我发现的..
在同一个服务中,我首先尝试我之前描述的内容,字符串返回空。
然后,如果我枚举每个系统级环境变量,它会找到我正在寻找的变量。
这是一个代码片段,根据 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);
}
试试这个代码字符串 getsyspath = System.Environment.GetEnvironmentVariable("TIP_HOME",EnvironmentVariableTarget.Machine);
您需要检查变量的存储方式。Set/GetEnvironmentVariable 有重载方法:
Environment.GetEnvironmentVariable 方法(字符串,EnvironmentVariableTarget)
问题是,存储环境变量( EnvironmentVariableTarget )有三种类型:
如果您将信息存储为机器或用户,那么您可以在运行时对其进行测试 Run (Win + R): %TIP_HOME%
希望能帮助到你 :)
服务通常在三个服务帐户之一下运行,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'
。如果它使用您的用户帐户,它将可以访问您通常可以访问的所有环境变量。
.
我将那行代码修改为:
字符串 t = System.Environment.GetEnvironmentVariable("TIP_HOME", EnvironmentVariableTarget.Machine);
我可以查看我的注册表并查看 TIP_HOME 是否已设置。
这来自 MSDN:机器:环境变量是从 Windows 操作系统注册表中的 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment 键存储或检索的。
用户变量存储在注册表中的其他位置。
但是,当我使用此更改运行服务时,字符串仍然显示为空。