Ensure appsettings.json is created in a writable location.
This commit is contained in:
parent
3bca495521
commit
6fdd6293ce
@ -11,7 +11,6 @@ using System.Threading.Tasks;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using ApplicationServices;
|
using ApplicationServices;
|
||||||
using Dinah.Core;
|
|
||||||
|
|
||||||
namespace LibationAvalonia
|
namespace LibationAvalonia
|
||||||
{
|
{
|
||||||
@ -53,7 +52,7 @@ namespace LibationAvalonia
|
|||||||
// check for existing settings in default location
|
// check for existing settings in default location
|
||||||
var defaultSettingsFile = Path.Combine(defaultLibationFilesDir, "Settings.json");
|
var defaultSettingsFile = Path.Combine(defaultLibationFilesDir, "Settings.json");
|
||||||
if (Configuration.SettingsFileIsValid(defaultSettingsFile))
|
if (Configuration.SettingsFileIsValid(defaultSettingsFile))
|
||||||
config.SetLibationFiles(defaultLibationFilesDir);
|
Configuration.SetLibationFiles(defaultLibationFilesDir);
|
||||||
|
|
||||||
if (config.LibationSettingsAreValid)
|
if (config.LibationSettingsAreValid)
|
||||||
{
|
{
|
||||||
@ -86,7 +85,7 @@ namespace LibationAvalonia
|
|||||||
// - error message, Exit()
|
// - error message, Exit()
|
||||||
if (setupDialog.IsNewUser)
|
if (setupDialog.IsNewUser)
|
||||||
{
|
{
|
||||||
setupDialog.Config.SetLibationFiles(Configuration.UserProfile);
|
Configuration.SetLibationFiles(Configuration.UserProfile);
|
||||||
ShowSettingsWindow(desktop, setupDialog.Config, OnSettingsCompleted);
|
ShowSettingsWindow(desktop, setupDialog.Config, OnSettingsCompleted);
|
||||||
}
|
}
|
||||||
else if (setupDialog.IsReturningUser)
|
else if (setupDialog.IsReturningUser)
|
||||||
@ -178,7 +177,7 @@ namespace LibationAvalonia
|
|||||||
|
|
||||||
private async void OnLibationFilesCompleted(IClassicDesktopStyleApplicationLifetime desktop, LibationFilesDialog libationFilesDialog, Configuration config)
|
private async void OnLibationFilesCompleted(IClassicDesktopStyleApplicationLifetime desktop, LibationFilesDialog libationFilesDialog, Configuration config)
|
||||||
{
|
{
|
||||||
config.SetLibationFiles(libationFilesDialog.SelectedDirectory);
|
Configuration.SetLibationFiles(libationFilesDialog.SelectedDirectory);
|
||||||
if (config.LibationSettingsAreValid)
|
if (config.LibationSettingsAreValid)
|
||||||
{
|
{
|
||||||
await RunMigrationsAsync(config);
|
await RunMigrationsAsync(config);
|
||||||
|
|||||||
@ -10,39 +10,6 @@ namespace LibationFileManager
|
|||||||
{
|
{
|
||||||
public partial class Configuration
|
public partial class Configuration
|
||||||
{
|
{
|
||||||
private static string getAppsettingsFile()
|
|
||||||
{
|
|
||||||
const string appsettings_filename = "appsettings.json";
|
|
||||||
const string empty_json = "{ }";
|
|
||||||
|
|
||||||
System.Collections.Generic.Queue<string> searchDirs = new();
|
|
||||||
|
|
||||||
searchDirs.Enqueue(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
|
|
||||||
searchDirs.Enqueue(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Libation"));
|
|
||||||
searchDirs.Enqueue(UserProfile);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
var appsettingsFile = Path.Combine(searchDirs.Dequeue(), appsettings_filename);
|
|
||||||
|
|
||||||
if (File.Exists(appsettingsFile))
|
|
||||||
return appsettingsFile;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.WriteAllText(appsettingsFile, empty_json);
|
|
||||||
return appsettingsFile;
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
while (searchDirs.Count > 0);
|
|
||||||
|
|
||||||
//We Could not find or create appsettings.json.
|
|
||||||
//As a Hail Mary, create it in temp files.
|
|
||||||
var tempAppsettings = Path.GetTempFileName();
|
|
||||||
File.WriteAllText(tempAppsettings, empty_json);
|
|
||||||
return tempAppsettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string APPSETTINGS_JSON { get; } = getAppsettingsFile();
|
private static string APPSETTINGS_JSON { get; } = getAppsettingsFile();
|
||||||
|
|
||||||
private const string LIBATION_FILES_KEY = "LibationFiles";
|
private const string LIBATION_FILES_KEY = "LibationFiles";
|
||||||
@ -78,31 +45,58 @@ namespace LibationFileManager
|
|||||||
|
|
||||||
private static string libationFilesPathCache { get; set; }
|
private static string libationFilesPathCache { get; set; }
|
||||||
|
|
||||||
private string getLibationFilesSettingFromJson()
|
private static string getAppsettingsFile()
|
||||||
|
{
|
||||||
|
const string appsettings_filename = "appsettings.json";
|
||||||
|
|
||||||
|
//Possible appsettings.json locations, in order of preference.
|
||||||
|
string[] possibleAppsettingsFiles = new[]
|
||||||
|
{
|
||||||
|
Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), appsettings_filename),
|
||||||
|
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Libation", appsettings_filename),
|
||||||
|
Path.Combine(UserProfile, appsettings_filename),
|
||||||
|
Path.Combine(Path.GetTempPath(), "Libation", appsettings_filename)
|
||||||
|
};
|
||||||
|
|
||||||
|
//Try to find and validate appsettings.json in each folder
|
||||||
|
foreach (var appsettingsFile in possibleAppsettingsFiles)
|
||||||
|
{
|
||||||
|
if (File.Exists(appsettingsFile))
|
||||||
{
|
{
|
||||||
string startingContents = null;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
startingContents = File.ReadAllText(APPSETTINGS_JSON);
|
var appSettings = JObject.Parse(File.ReadAllText(appsettingsFile));
|
||||||
var startingJObj = JObject.Parse(startingContents);
|
|
||||||
|
|
||||||
if (startingJObj.ContainsKey(LIBATION_FILES_KEY))
|
if (appSettings.ContainsKey(LIBATION_FILES_KEY)
|
||||||
{
|
&& appSettings[LIBATION_FILES_KEY] is JValue jval
|
||||||
var startingValue = startingJObj[LIBATION_FILES_KEY].Value<string>();
|
&& jval.Value is string settingsPath
|
||||||
if (!string.IsNullOrWhiteSpace(startingValue))
|
&& !string.IsNullOrWhiteSpace(settingsPath))
|
||||||
return startingValue;
|
return appsettingsFile;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
}
|
||||||
// not found. write to file. read from file
|
|
||||||
var endingContents = new JObject { { LIBATION_FILES_KEY, UserProfile.ToString() } }.ToString(Formatting.Indented);
|
|
||||||
if (startingContents != endingContents)
|
|
||||||
{
|
|
||||||
File.WriteAllText(APPSETTINGS_JSON, endingContents);
|
|
||||||
System.Threading.Thread.Sleep(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Valid appsettings.json not found. Try to create it in each folder.
|
||||||
|
var endingContents = new JObject { { LIBATION_FILES_KEY, UserProfile } }.ToString(Formatting.Indented);
|
||||||
|
foreach (var appsettingsFile in possibleAppsettingsFiles)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(appsettingsFile, endingContents);
|
||||||
|
return appsettingsFile;
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, $"Failed to create {appsettingsFile}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ApplicationException($"Could not locate or create {appsettings_filename}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string getLibationFilesSettingFromJson()
|
||||||
|
{
|
||||||
// do not check whether directory exists. special/meta directory (eg: AppDir) is valid
|
// do not check whether directory exists. special/meta directory (eg: AppDir) is valid
|
||||||
// verify from live file. no try/catch. want failures to be visible
|
// verify from live file. no try/catch. want failures to be visible
|
||||||
var jObjFinal = JObject.Parse(File.ReadAllText(APPSETTINGS_JSON));
|
var jObjFinal = JObject.Parse(File.ReadAllText(APPSETTINGS_JSON));
|
||||||
@ -110,16 +104,8 @@ namespace LibationFileManager
|
|||||||
return valueFinal;
|
return valueFinal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLibationFiles(string directory)
|
public static void SetLibationFiles(string directory)
|
||||||
{
|
{
|
||||||
// ensure exists
|
|
||||||
if (!File.Exists(APPSETTINGS_JSON))
|
|
||||||
{
|
|
||||||
// getter creates new file, loads PersistentDictionary
|
|
||||||
var _ = LibationFiles;
|
|
||||||
System.Threading.Thread.Sleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
libationFilesPathCache = null;
|
libationFilesPathCache = null;
|
||||||
|
|
||||||
var startingContents = File.ReadAllText(APPSETTINGS_JSON);
|
var startingContents = File.ReadAllText(APPSETTINGS_JSON);
|
||||||
@ -131,14 +117,26 @@ namespace LibationFileManager
|
|||||||
if (startingContents == endingContents)
|
if (startingContents == endingContents)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
// now it's set in the file again but no settings have moved yet
|
// now it's set in the file again but no settings have moved yet
|
||||||
File.WriteAllText(APPSETTINGS_JSON, endingContents);
|
File.WriteAllText(APPSETTINGS_JSON, endingContents);
|
||||||
|
|
||||||
|
tryLog(() => Log.Logger.Information("Libation files changed {@DebugInfo}", new { APPSETTINGS_JSON, LIBATION_FILES_KEY, directory }));
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
tryLog(() => Log.Logger.Error(ex, "Failed to change Libation files location {@DebugInfo}", new { APPSETTINGS_JSON, LIBATION_FILES_KEY, directory }));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tryLog(Action logAction)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.Logger.Information("Libation files changed {@DebugInfo}", new { APPSETTINGS_JSON, LIBATION_FILES_KEY, directory });
|
logAction();
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -92,7 +92,7 @@ namespace LibationWinForms
|
|||||||
// check for existing settings in default location
|
// check for existing settings in default location
|
||||||
var defaultSettingsFile = Path.Combine(defaultLibationFilesDir, "Settings.json");
|
var defaultSettingsFile = Path.Combine(defaultLibationFilesDir, "Settings.json");
|
||||||
if (Configuration.SettingsFileIsValid(defaultSettingsFile))
|
if (Configuration.SettingsFileIsValid(defaultSettingsFile))
|
||||||
config.SetLibationFiles(defaultLibationFilesDir);
|
Configuration.SetLibationFiles(defaultLibationFilesDir);
|
||||||
|
|
||||||
if (config.LibationSettingsAreValid)
|
if (config.LibationSettingsAreValid)
|
||||||
return;
|
return;
|
||||||
@ -112,7 +112,7 @@ namespace LibationWinForms
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (setupDialog.IsNewUser)
|
if (setupDialog.IsNewUser)
|
||||||
config.SetLibationFiles(defaultLibationFilesDir);
|
Configuration.SetLibationFiles(defaultLibationFilesDir);
|
||||||
else if (setupDialog.IsReturningUser)
|
else if (setupDialog.IsReturningUser)
|
||||||
{
|
{
|
||||||
var libationFilesDialog = new LibationFilesDialog();
|
var libationFilesDialog = new LibationFilesDialog();
|
||||||
@ -123,7 +123,7 @@ namespace LibationWinForms
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.SetLibationFiles(libationFilesDialog.SelectedDirectory);
|
Configuration.SetLibationFiles(libationFilesDialog.SelectedDirectory);
|
||||||
if (config.LibationSettingsAreValid)
|
if (config.LibationSettingsAreValid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user