diff --git a/doc/xmlConfigFile.md b/doc/xmlConfigFile.md
index f5536e7..ccbbcab 100644
--- a/doc/xmlConfigFile.md
+++ b/doc/xmlConfigFile.md
@@ -139,6 +139,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 an 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/doc/yamlConfigFile.md b/doc/yamlConfigFile.md
index 33bd88b..2dc169b 100644
--- a/doc/yamlConfigFile.md
+++ b/doc/yamlConfigFile.md
@@ -171,6 +171,14 @@ env:
value: host1;host2
```
+### 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 an lines starting with "#" are ignored. The syntax is:
+
+```yaml
+envFile: '%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/DefaultSettings.cs b/src/WinSW.Core/Configuration/DefaultSettings.cs
index acabcc7..2025b06 100644
--- a/src/WinSW.Core/Configuration/DefaultSettings.cs
+++ b/src/WinSW.Core/Configuration/DefaultSettings.cs
@@ -129,6 +129,8 @@ namespace WinSW.Configuration
public Dictionary EnvironmentVariables => new(0);
+ public string? EnvironmentVariablesFile => null;
+
// Misc
public bool BeepOnShutdown => false;
diff --git a/src/WinSW.Core/Configuration/XmlServiceConfig.cs b/src/WinSW.Core/Configuration/XmlServiceConfig.cs
index b1bbbda..3a26b44 100644
--- a/src/WinSW.Core/Configuration/XmlServiceConfig.cs
+++ b/src/WinSW.Core/Configuration/XmlServiceConfig.cs
@@ -65,6 +65,8 @@ namespace WinSW
// Also inject system environment variables
Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameServiceId, this.Name);
+ this.LoadEnvironmentVariablesFromFile();
+
this.environmentVariables = this.LoadEnvironmentVariables();
}
@@ -528,6 +530,11 @@ namespace WinSW
///
public Dictionary EnvironmentVariables => new(this.environmentVariables);
+ ///
+ /// File from which environment variables are loaded.
+ ///
+ public string? EnvironmentVariablesFile => this.SingleElement("envFile", optional: true);
+
///
/// List of downloads to be performed by the wrapper before starting
/// a service.
@@ -690,6 +697,18 @@ namespace WinSW
return environment;
}
+ private void LoadEnvironmentVariablesFromFile()
+ {
+ var envFile = this.SingleElement("envFile", optional: true);
+
+ if (envFile is null)
+ {
+ return;
+ }
+
+ ConfigHelper.LoadEnvironmentVariablesFile(envFile);
+ }
+
public List? YamlExtensions => Defaults.YamlExtensions;
}
}
diff --git a/src/WinSW.Core/Configuration/YamlServiceConfig.cs b/src/WinSW.Core/Configuration/YamlServiceConfig.cs
index b6613d3..42d8515 100644
--- a/src/WinSW.Core/Configuration/YamlServiceConfig.cs
+++ b/src/WinSW.Core/Configuration/YamlServiceConfig.cs
@@ -43,6 +43,8 @@ namespace WinSW.Configuration
// Also inject system environment variables
Environment.SetEnvironmentVariable(WinSWSystem.EnvVarNameServiceId, this.Name);
+ this.LoadEnvironmentVariablesFromFile();
+
this.LoadEnvironmentVariables();
}
@@ -201,6 +203,8 @@ namespace WinSW.Configuration
public Dictionary EnvironmentVariables { get; set; } = new Dictionary();
+ public string? EnvironmentVariablesFile => Expand(this.raw.EnvFile) ?? this.defaults.EnvironmentVariablesFile;
+
public void LoadEnvironmentVariables()
{
if (this.raw.Env is null)
@@ -224,6 +228,18 @@ namespace WinSW.Configuration
}
}
+ private void LoadEnvironmentVariablesFromFile()
+ {
+ string? envFile = Expand(this.raw.EnvFile);
+
+ if (envFile is null)
+ {
+ return;
+ }
+
+ ConfigHelper.LoadEnvironmentVariablesFile(envFile);
+ }
+
public ServiceAccount ServiceAccount
{
get
@@ -315,6 +331,7 @@ namespace WinSW.Configuration
public string? Priority;
public string? BeepOnShutdown;
public List? Env;
+ public string? EnvFile;
public List? OnFailure;
public string? DelayedAutoStart;
public string? SecurityDescriptor;
diff --git a/src/WinSW.Core/Util/ConfigHelper.cs b/src/WinSW.Core/Util/ConfigHelper.cs
index 2ff1978..10a71d0 100644
--- a/src/WinSW.Core/Util/ConfigHelper.cs
+++ b/src/WinSW.Core/Util/ConfigHelper.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
namespace WinSW.Util
{
@@ -45,5 +46,29 @@ namespace WinSW.Util
return false;
}
+
+ public static void LoadEnvironmentVariablesFile(string envFile)
+ {
+ 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 (env-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);
+ }
+ }
}
}