C
C#6mo ago
engineertdog

Update configuration in memory

I have the class below where I'm trying to provide default values if a user doesn't configure them in appsettings. Supposedly, this is supposed to work, but it's not working in practices. Do you have any recommendations to either fix this, or to just use default values regardless and screw the config?
c#
public static class MainelyLog {
private readonly static IConfigurationRoot _configuration;
private readonly static string _appDirectory = AppDomain.CurrentDomain.BaseDirectory;

static MainelyLog() {
_configuration = new ConfigurationBuilder()
.SetBasePath(_appDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
}

public static void SetupLogging(string defaultLogPath) {
IConfigurationSection? logConfig = _configuration.GetSection("Serilog:WriteTo")
.GetChildren()
.FirstOrDefault(c => c["Name"] == "File");

if (logConfig != null && !Path.IsPathFullyQualified(logConfig["Args:path"])) {
string logPath = logConfig["Args:path"] ?? defaultLogPath;
if (logPath.StartsWith(".\\")) { logPath = logPath[2..]; }
logConfig["Args:path"] = Path.Combine(_appDirectory, logPath);
}

Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(_configuration)
.CreateLogger();
}
}
c#
public static class MainelyLog {
private readonly static IConfigurationRoot _configuration;
private readonly static string _appDirectory = AppDomain.CurrentDomain.BaseDirectory;

static MainelyLog() {
_configuration = new ConfigurationBuilder()
.SetBasePath(_appDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
}

public static void SetupLogging(string defaultLogPath) {
IConfigurationSection? logConfig = _configuration.GetSection("Serilog:WriteTo")
.GetChildren()
.FirstOrDefault(c => c["Name"] == "File");

if (logConfig != null && !Path.IsPathFullyQualified(logConfig["Args:path"])) {
string logPath = logConfig["Args:path"] ?? defaultLogPath;
if (logPath.StartsWith(".\\")) { logPath = logPath[2..]; }
logConfig["Args:path"] = Path.Combine(_appDirectory, logPath);
}

Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(_configuration)
.CreateLogger();
}
}
The purpose of doing this is to account for relative paths not being correct when running interactively vs as a service.
37 Replies
engineertdog
engineertdogOP6mo ago
Optionally, maybe an easier route is to correctly set the base directory for the app. If running as a Windows service sets it to C:\Windows\system32, then I could set the base directory to the executable directory?
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
So, I did that. But even though the ContentRoot is set correctly, it still has the app base set to C:\windows\system32 which messes up the relative paths. I worked around that by doing this.
c#
if (!Environment.UserInteractive) {
// Setup Windows Service
builder.Services.AddWindowsService();
Directory.SetCurrentDirectory(AppContext.BaseDirectory); // in theory, this line shouldn't be needed, but apparently it is
}

// Logging
MainelyLog.SetupLogging(builder.Configuration);
builder.Services.AddLogging(loggingBuilder => {
loggingBuilder.AddSerilog(dispose: true);
});
c#
if (!Environment.UserInteractive) {
// Setup Windows Service
builder.Services.AddWindowsService();
Directory.SetCurrentDirectory(AppContext.BaseDirectory); // in theory, this line shouldn't be needed, but apparently it is
}

// Logging
MainelyLog.SetupLogging(builder.Configuration);
builder.Services.AddLogging(loggingBuilder => {
loggingBuilder.AddSerilog(dispose: true);
});
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
Sets the content root to AppContext.BaseDirectory. For more information, see the Current directory and content root section.
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
No, that's what it says .AddWindowsService() does. Which - is correct. ContentRoot is correct. But the app directory isn't
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
I can't share the repo, it's internal
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
But I can do this
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
I extracted out everything and made a simple app on my local system. Windows 11 & server 2022 are fine. Same configuration on Windows 2019 appears to be where it defaults to system32 still. @TeBeCo
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
Nah, ran the same command. Just a simple sc.exe create <name> binpath= ""
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
These are also likely heavily modified OS's from the cyber security team
MODiX
MODiX6mo ago
TeBeCo
might have miss configured the service itself when you did sc create or something
Quoted by
React with ❌ to remove this embed.
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
Yeah, well at least my sanity is straight now. I appreciate it
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
If I get some time, I'll get virtualbox up and test a clean 2019 iso
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
Otherwise it's all the mods they do on the images. But even at that, I'm fine with having 1 extra lina of code (well, 2 extra lines for adding the if statement that's not really required).
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
Wait, I lied. I actually forgot to remove that line.
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
I'll have the code in 1 sec
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
I was, but I actually went with Quartz for scheduling. So it's similar but different https://gitlab.com/engineertdog/windows-service-directory
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
You'd do just a plain console app with the scheduled services, or use something other than Quartz?
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
Yeah, I just started with the worker template but changed to a cron based schedule for running it
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
engineertdog
engineertdogOP6mo ago
Yeah, it just doesn't seem to be setting the current directory. But one line of code to fix that is not a big deal
Unknown User
Unknown User6mo ago
Message Not Public
Sign In & Join Server To View
Want results from more Discord servers?
Add your server