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);