diff --git a/docs/xml-config-file.md b/docs/xml-config-file.md
index 1514ad1..d4e13fa 100644
--- a/docs/xml-config-file.md
+++ b/docs/xml-config-file.md
@@ -219,6 +219,14 @@ This optional element can be specified multiple times if necessary to specify en
```
+### Environment File
+
+This optional element can be specified one time to specify a file to load environment variables from. Each variable definition must be on a separate line and in the format "key=value". Empty lines and lines starting with "#" are ignored. The syntax is:
+
+```xml
+%BASE%/env.txt
+```
+
### interactive
If this optional element is specified, the service will be allowed to interact with the desktop, such as by showing a new window and dialog boxes.
diff --git a/src/WinSW.Core/Configuration/XmlServiceConfig.cs b/src/WinSW.Core/Configuration/XmlServiceConfig.cs
index 07021a5..47986ad 100644
--- a/src/WinSW.Core/Configuration/XmlServiceConfig.cs
+++ b/src/WinSW.Core/Configuration/XmlServiceConfig.cs
@@ -78,6 +78,8 @@ namespace WinSW
// Also inject system environment variables
Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameServiceId, this.Name);
+ this.LoadEnvironmentVariablesFromFile();
+
this.environmentVariables = this.LoadEnvironmentVariables();
}
@@ -449,6 +451,11 @@ namespace WinSW
///
public override Dictionary EnvironmentVariables => this.environmentVariables;
+ ///
+ /// File from which environment variables are loaded.
+ ///
+ public string? EnvironmentVariablesFile => this.SingleElementOrNull("envFile");
+
///
/// List of downloads to be performed by the wrapper before starting
/// a service.
@@ -623,6 +630,37 @@ namespace WinSW
return environment;
}
+ private void LoadEnvironmentVariablesFromFile()
+ {
+ var envFile = this.SingleElementOrNull("envFile");
+
+ if (envFile is null)
+ {
+ return;
+ }
+
+ foreach (string line in File.ReadAllLines(envFile))
+ {
+ if (line.Length == 0 || line.StartsWith("#"))
+ {
+ // ignore empty lines and comments
+ continue;
+ }
+
+ int equalsSignIndex = line.IndexOf("=");
+
+ if (equalsSignIndex == -1)
+ {
+ throw new WinSWException("The environment variables file contains one or more invalid entries. Each variable definition must be on a separate line and in the format \"key=value\".");
+ }
+
+ string key = line.Substring(0, equalsSignIndex);
+ string value = line.Substring(equalsSignIndex + 1);
+
+ Environment.SetEnvironmentVariable(key, value);
+ }
+ }
+
private ProcessCommand GetProcessCommand(string name)
{
var node = this.root.SelectSingleNode(name);