using System; using System.IO; namespace LibationFileManager; /// /// Ensures OS interop assembly resolution and required dependency files are ready before background library load. /// public static class StartupAssemblyBootstrap { public const string EntityFrameworkCoreSqliteAssemblyFileName = "Microsoft.EntityFrameworkCore.Sqlite.dll"; /// /// Registers assembly resolution and verifies required install-folder assemblies exist. /// Call before Task.Run loads the library or opens the database on a thread-pool thread. /// public static void PrepareForBackgroundDataAccess() { _ = InteropFactory.InteropFunctionsType; ValidateEntityFrameworkCoreSqlitePresent(); } public static string GetLibraryLoadFailureMessage() => $""" Libation could not load its database components (Entity Framework Core for SQLite). This often happens after an incomplete in-app upgrade. Quit Libation completely, then install a fresh copy of the latest release to a new folder (do not overlay files on top of the old install). Install folder: {Configuration.ProcessDirectory} Expected file: {Path.Combine(Configuration.ProcessDirectory, EntityFrameworkCoreSqliteAssemblyFileName)} """; public static bool IsMissingDependencyAssembly(Exception ex) { for (var current = ex; current is not null; current = current.InnerException) { if (current is not FileNotFoundException and not FileLoadException) continue; var name = (current as FileNotFoundException)?.FileName ?? current.Message; if (name.Contains("EntityFrameworkCore", StringComparison.OrdinalIgnoreCase) || name.Contains("Microsoft.Data.Sqlite", StringComparison.OrdinalIgnoreCase)) return true; } return false; } private static void ValidateEntityFrameworkCoreSqlitePresent() { var path = Path.Combine(Configuration.ProcessDirectory, EntityFrameworkCoreSqliteAssemblyFileName); if (File.Exists(path)) return; throw new FileNotFoundException( $"Required file '{EntityFrameworkCoreSqliteAssemblyFileName}' was not found in the Libation install folder.{Environment.NewLine}{Environment.NewLine}{GetLibraryLoadFailureMessage()}", path); } }