Say why the folders cannot be made instead of dying

Something already sitting where Documents/N1MM Logger+ should go — a file, or
a link to somewhere that is not there — threw out of Directory.CreateDirectory
before the program had a window, so the operator got a stack trace and nothing
else.

CreateFolders answers with what stopped it, and the program shows it in a
window naming the path and stops there. NONEMM_HOME moves the whole lot
somewhere else, for a station that keeps its files off the Documents folder.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
This commit is contained in:
2026-08-31 23:16:55 +00:00
co-authored by Claude Opus 5
parent d5b5233ab8
commit 14209e01e8
5 changed files with 125 additions and 6 deletions
+31 -3
View File
@@ -33,7 +33,13 @@ public sealed class UserPaths
Own = Path.Combine(root, "Nonemm");
}
public static UserPaths Default() => new(DefaultRoot());
/// `NONEMM_HOME` moves the whole lot somewhere else, for a station that
/// keeps its files off the Documents folder or runs two copies side by
/// side.
public static UserPaths Default() =>
new(Environment.GetEnvironmentVariable("NONEMM_HOME") is { Length: > 0 } wanted
? wanted
: DefaultRoot());
public string Root { get; }
@@ -97,12 +103,34 @@ public sealed class UserPaths
? Wav
: Path.Combine(Wav, operatorCallsign.Trim().ToUpperInvariant());
public void CreateFolders()
/// Makes every folder, and answers with what stopped it rather than
/// throwing: this runs before there is a window to report anything in, and
/// a program that dies with a stack trace tells the operator nothing.
public string? CreateFolders()
{
foreach (string folder in All())
{
Directory.CreateDirectory(folder);
if (Directory.Exists(folder))
{
continue;
}
if (File.Exists(folder))
{
return $"{folder} is a file, not a folder. Move it out of the way and start again.";
}
try
{
Directory.CreateDirectory(folder);
}
catch (Exception failure) when (failure is IOException or UnauthorizedAccessException)
{
// something is already there that is neither a file nor a
// folder — a link to somewhere that is not there is the usual
// one — or the disk will not have it
return $"{folder} could not be made: {failure.Message}";
}
}
return null;
}
/// Every folder that is made at startup, the root first.