diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor
index 155a0c72..a1cd7e47 100644
--- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor
+++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor
@@ -91,7 +91,7 @@
{
try
{
- await PackageService.DownloadPackageAsync(packageid, version, "Modules");
+ await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await logger.LogInformation("Module {ModuleDefinitionName} {Version} Downloaded Successfully", packageid, version);
AddModuleMessage(Localizer["Modules Downloaded Successfully. Click Install To Complete Installation."], MessageType.Success);
StateHasChanged();
diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
index 1ffc631b..c9c47456 100644
--- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
+++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
@@ -85,7 +85,7 @@ else
{
try
{
- await PackageService.DownloadPackageAsync(packagename, version, "Modules");
+ await PackageService.DownloadPackageAsync(packagename, version, "Packages");
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
AddModuleMessage(Localizer["Module Installed Successfully. You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
@@ -103,7 +103,7 @@ else
{
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
AddModuleMessage(Localizer["Module Deleted Successfully"], MessageType.Success);
- StateHasChanged();
+ NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload"));
}
catch (Exception ex)
{
diff --git a/Oqtane.Client/Modules/Admin/Themes/Add.razor b/Oqtane.Client/Modules/Admin/Themes/Add.razor
index 24501517..b0233be0 100644
--- a/Oqtane.Client/Modules/Admin/Themes/Add.razor
+++ b/Oqtane.Client/Modules/Admin/Themes/Add.razor
@@ -91,7 +91,7 @@
{
try
{
- await PackageService.DownloadPackageAsync(packageid, version, "Themes");
+ await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await logger.LogInformation("Theme {ThemeName} {Version} Downloaded Successfully", packageid, version);
AddModuleMessage(Localizer["Themes Downloaded Successfully. Click Install To Complete Installation."], MessageType.Success);
StateHasChanged();
diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor
index 60df31cb..fc13417f 100644
--- a/Oqtane.Client/Modules/Admin/Themes/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor
@@ -86,7 +86,7 @@ else
{
try
{
- await PackageService.DownloadPackageAsync(packagename, version, "Themes");
+ await PackageService.DownloadPackageAsync(packagename, version, "Packages");
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
await ThemeService.InstallThemesAsync();
AddModuleMessage(Localizer["Theme Installed Successfully. You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
@@ -104,7 +104,7 @@ else
{
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
AddModuleMessage(Localizer["Theme Deleted Successfully"], MessageType.Success);
- StateHasChanged();
+ NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload"));
}
catch (Exception ex)
{
diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs
index 30d73d66..b0420ca8 100644
--- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs
+++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs
@@ -90,7 +90,7 @@ namespace Oqtane.Controllers
public void InstallModules()
{
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Modules Installed");
- _installationManager.InstallPackages("Modules");
+ _installationManager.InstallPackages();
}
// DELETE api//5?siteid=x
@@ -128,25 +128,8 @@ namespace Oqtane.Controllers
}
// remove module assets
- string assetpath = Path.Combine(_environment.WebRootPath, "Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName));
- if (System.IO.File.Exists(Path.Combine(assetpath, "assets.json")))
+ if (_installationManager.UninstallPackage(moduledefinition.PackageName))
{
- // use assets.json to clean up file resources
- List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json")));
- assets.Reverse();
- foreach(string asset in assets)
- {
- // legacy support for assets that were stored as absolute paths
- string filepath = asset.StartsWith("\\") ? Path.Combine(_environment.ContentRootPath, asset.Substring(1)) : asset;
- if (System.IO.File.Exists(filepath))
- {
- System.IO.File.Delete(filepath);
- if (!Directory.EnumerateFiles(Path.GetDirectoryName(filepath)).Any())
- {
- Directory.Delete(Path.GetDirectoryName(filepath));
- }
- }
- }
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
}
else
@@ -160,6 +143,7 @@ namespace Oqtane.Controllers
}
// clean up module static resource folder
+ string assetpath = Path.Combine(_environment.WebRootPath, "Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName));
if (Directory.Exists(assetpath))
{
Directory.Delete(assetpath, true);
diff --git a/Oqtane.Server/Controllers/PackageController.cs b/Oqtane.Server/Controllers/PackageController.cs
index b61585b5..c5c94dc7 100644
--- a/Oqtane.Server/Controllers/PackageController.cs
+++ b/Oqtane.Server/Controllers/PackageController.cs
@@ -97,7 +97,7 @@ namespace Oqtane.Controllers
public void InstallPackages()
{
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Packages Installed");
- _installationManager.InstallPackages("Packages");
+ _installationManager.InstallPackages();
}
}
diff --git a/Oqtane.Server/Controllers/ThemeController.cs b/Oqtane.Server/Controllers/ThemeController.cs
index 5bf8a2f3..79e53e64 100644
--- a/Oqtane.Server/Controllers/ThemeController.cs
+++ b/Oqtane.Server/Controllers/ThemeController.cs
@@ -45,7 +45,7 @@ namespace Oqtane.Controllers
public void InstallThemes()
{
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Themes Installed");
- _installationManager.InstallPackages("Themes");
+ _installationManager.InstallPackages();
}
// DELETE api//xxx
@@ -58,25 +58,8 @@ namespace Oqtane.Controllers
if (theme != null && Utilities.GetAssemblyName(theme.ThemeName) != "Oqtane.Client")
{
// remove theme assets
- string assetpath = Path.Combine(_environment.WebRootPath, "Themes", Utilities.GetTypeName(theme.ThemeName));
- if (System.IO.File.Exists(Path.Combine(assetpath, "assets.json")))
+ if (_installationManager.UninstallPackage(theme.PackageName))
{
- // use assets.json to clean up file resources
- List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json")));
- assets.Reverse();
- foreach (string asset in assets)
- {
- // legacy support for assets that were stored as absolute paths
- string filepath = (asset.StartsWith("\\")) ? Path.Combine(_environment.ContentRootPath, asset.Substring(1)) : asset;
- if (System.IO.File.Exists(filepath))
- {
- System.IO.File.Delete(filepath);
- if (!Directory.EnumerateFiles(Path.GetDirectoryName(filepath)).Any())
- {
- Directory.Delete(Path.GetDirectoryName(filepath));
- }
- }
- }
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Assets Removed For {ThemeName}", theme.ThemeName);
}
else
@@ -90,10 +73,10 @@ namespace Oqtane.Controllers
}
// clean up theme static resource folder
- string folder = Path.Combine(_environment.WebRootPath, "Themes" , Utilities.GetTypeName(theme.ThemeName));
- if (Directory.Exists(folder))
+ string assetpath = Path.Combine(_environment.WebRootPath, "Themes", Utilities.GetTypeName(theme.ThemeName));
+ if (Directory.Exists(assetpath))
{
- Directory.Delete(folder, true);
+ Directory.Delete(assetpath, true);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Static Resource Folder Removed For {ThemeName}", theme.ThemeName);
}
diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs
index 7967d8c3..6a9ba2ba 100644
--- a/Oqtane.Server/Infrastructure/DatabaseManager.cs
+++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs
@@ -17,7 +17,6 @@ using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Shared;
using Oqtane.Enums;
-using Oqtane.Interfaces;
using File = System.IO.File;
// ReSharper disable MemberCanBePrivate.Global
@@ -205,7 +204,7 @@ namespace Oqtane.Infrastructure
using (var scope = _serviceScopeFactory.CreateScope())
{
var installationManager = scope.ServiceProvider.GetRequiredService();
- installationManager.InstallPackages(packageFolderName);
+ installationManager.InstallPackages();
result.Success = true;
}
}
diff --git a/Oqtane.Server/Infrastructure/InstallationManager.cs b/Oqtane.Server/Infrastructure/InstallationManager.cs
index ef3b0b7e..2f43f308 100644
--- a/Oqtane.Server/Infrastructure/InstallationManager.cs
+++ b/Oqtane.Server/Infrastructure/InstallationManager.cs
@@ -3,11 +3,11 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
+using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Xml;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Hosting;
using Oqtane.Shared;
// ReSharper disable AssignNullToNotNullAttribute
@@ -18,125 +18,138 @@ namespace Oqtane.Infrastructure
{
private readonly IHostApplicationLifetime _hostApplicationLifetime;
private readonly IWebHostEnvironment _environment;
- private readonly IMemoryCache _cache;
- public InstallationManager(IHostApplicationLifetime hostApplicationLifetime, IWebHostEnvironment environment, IMemoryCache cache)
+ public InstallationManager(IHostApplicationLifetime hostApplicationLifetime, IWebHostEnvironment environment)
{
_hostApplicationLifetime = hostApplicationLifetime;
_environment = environment;
- _cache = cache;
}
- public void InstallPackages(string folders)
+ public void InstallPackages()
{
- if (!InstallPackages(folders, _environment.WebRootPath, _environment.ContentRootPath))
+ if (!InstallPackages(_environment.WebRootPath, _environment.ContentRootPath))
{
// error installing packages
}
}
- public static bool InstallPackages(string folders, string webRootPath, string contentRootPath)
+ public static bool InstallPackages(string webRootPath, string contentRootPath)
{
bool install = false;
string binPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
- foreach (string folder in folders.Split(','))
+ string sourceFolder = Path.Combine(webRootPath, "Packages");
+ if (!Directory.Exists(sourceFolder))
{
- string sourceFolder = Path.Combine(webRootPath, folder);
- if (!Directory.Exists(sourceFolder))
- {
- Directory.CreateDirectory(sourceFolder);
- }
+ Directory.CreateDirectory(sourceFolder);
+ }
- // iterate through Nuget packages in source folder
- foreach (string packagename in Directory.GetFiles(sourceFolder, "*.nupkg"))
+ // support for legacy folder locations
+ foreach (var folder in "Modules,Themes".Split(","))
+ {
+ foreach(var file in Directory.GetFiles(Path.Combine(webRootPath, folder), "*.nupkg"))
{
- // iterate through files
- using (ZipArchive archive = ZipFile.OpenRead(packagename))
+ var destinationFile = Path.Combine(sourceFolder, Path.GetFileName(file));
+ if (File.Exists(destinationFile))
{
- string frameworkversion = "";
- // locate nuspec
- foreach (ZipArchiveEntry entry in archive.Entries)
+ File.Delete(destinationFile);
+ }
+ File.Move(file, destinationFile);
+ }
+ }
+
+ // iterate through Nuget packages in source folder
+ foreach (string packagename in Directory.GetFiles(sourceFolder, "*.nupkg"))
+ {
+ // iterate through files
+ using (ZipArchive archive = ZipFile.OpenRead(packagename))
+ {
+ string frameworkversion = "";
+ // locate nuspec
+ foreach (ZipArchiveEntry entry in archive.Entries)
+ {
+ if (entry.FullName.ToLower().EndsWith(".nuspec"))
{
- if (entry.FullName.ToLower().EndsWith(".nuspec"))
+ // open nuspec
+ XmlTextReader reader = new XmlTextReader(entry.Open());
+ reader.Namespaces = false; // remove namespace
+ XmlDocument doc = new XmlDocument();
+ doc.Load(reader);
+ // get framework dependency
+ XmlNode node = doc.SelectSingleNode("/package/metadata/dependencies/dependency[@id='Oqtane.Framework']");
+ if (node != null)
{
- // open nuspec
- XmlTextReader reader = new XmlTextReader(entry.Open());
- reader.Namespaces = false; // remove namespace
- XmlDocument doc = new XmlDocument();
- doc.Load(reader);
- // get framework dependency
- XmlNode node = doc.SelectSingleNode("/package/metadata/dependencies/dependency[@id='Oqtane.Framework']");
- if (node != null)
- {
- frameworkversion = node.Attributes["version"].Value;
- }
-
- reader.Close();
- }
- }
-
- // if compatible with framework version
- if (frameworkversion == "" || Version.Parse(Constants.Version).CompareTo(Version.Parse(frameworkversion)) >= 0)
- {
- List assets = new List();
- bool manifest = false;
-
- // packages are in form of name.1.0.0.nupkg or name.culture.1.0.0.nupkg
- string name = Path.GetFileNameWithoutExtension(packagename);
- string[] segments = name?.Split('.');
- if (segments != null) name = string.Join('.', segments, 0, segments.Length - 3); // remove version information
-
- // deploy to appropriate locations
- foreach (ZipArchiveEntry entry in archive.Entries)
- {
- string filename = "";
-
- // evaluate entry root folder
- switch (entry.FullName.Split('/')[0])
- {
- case "lib": // lib/net5.0/...
- filename = ExtractFile(entry, binPath, 2);
- break;
- case "wwwroot": // wwwroot/...
- filename = ExtractFile(entry, webRootPath, 1);
- break;
- case "runtimes": // runtimes/name/...
- filename = ExtractFile(entry, binPath, 0);
- break;
- }
-
- if (filename != "")
- {
- assets.Add(filename.Replace(contentRootPath, ""));
- if (!manifest && Path.GetFileName(filename) == "assets.json")
- {
- manifest = true;
- }
- }
- }
-
- // save dynamic list of assets
- if (!manifest && assets.Count != 0)
- {
- string manifestpath = Path.Combine(webRootPath, folder, name, "assets.json");
- if (File.Exists(manifestpath))
- {
- File.Delete(manifestpath);
- }
- if (!Directory.Exists(Path.GetDirectoryName(manifestpath)))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(manifestpath));
- }
- File.WriteAllText(manifestpath, JsonSerializer.Serialize(assets));
+ frameworkversion = node.Attributes["version"].Value;
}
+ reader.Close();
+ break;
}
}
- // remove package
- File.Delete(packagename);
- install = true;
+ // if compatible with framework version
+ if (frameworkversion == "" || Version.Parse(Constants.Version).CompareTo(Version.Parse(frameworkversion)) >= 0)
+ {
+ List assets = new List();
+ bool manifest = false;
+
+ // packages are in form of name.1.0.0.nupkg or name.culture.1.0.0.nupkg
+ string name = Path.GetFileNameWithoutExtension(packagename);
+ string[] segments = name?.Split('.');
+ // remove version information from name
+ if (segments != null) name = string.Join('.', segments, 0, segments.Length - 3);
+
+ // deploy to appropriate locations
+ foreach (ZipArchiveEntry entry in archive.Entries)
+ {
+ string filename = "";
+
+ // evaluate entry root folder
+ switch (entry.FullName.Split('/')[0])
+ {
+ case "lib": // lib/net5.0/...
+ filename = ExtractFile(entry, binPath, 2);
+ break;
+ case "wwwroot": // wwwroot/...
+ filename = ExtractFile(entry, webRootPath, 1);
+ break;
+ case "runtimes": // runtimes/name/...
+ filename = ExtractFile(entry, binPath, 0);
+ break;
+ case "ref": // ref/net5.0/...
+ filename = ExtractFile(entry, Path.Combine(binPath, "ref"), 2);
+ break;
+ }
+
+ if (filename != "")
+ {
+ assets.Add(filename.Replace(contentRootPath, ""));
+ if (!manifest && Path.GetFileName(filename) == name + ".log")
+ {
+ manifest = true;
+ }
+ }
+ }
+
+ // save dynamic list of assets
+ if (!manifest && assets.Count != 0)
+ {
+ string manifestpath = Path.Combine(sourceFolder, name + ".log");
+ if (File.Exists(manifestpath))
+ {
+ File.Delete(manifestpath);
+ }
+ if (!Directory.Exists(Path.GetDirectoryName(manifestpath)))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(manifestpath));
+ }
+ File.WriteAllText(manifestpath, JsonSerializer.Serialize(assets));
+ }
+ }
}
+
+ // remove package
+ File.Delete(packagename);
+ install = true;
}
return install;
@@ -163,6 +176,31 @@ namespace Oqtane.Infrastructure
return filename;
}
+ public bool UninstallPackage(string PackageName)
+ {
+ if (File.Exists(Path.Combine(_environment.WebRootPath, "Packages", PackageName + ".log")))
+ {
+ // use manifest to clean up file resources
+ List assets = JsonSerializer.Deserialize>(File.ReadAllText(Path.Combine(_environment.WebRootPath, "Packages", PackageName + ".log")));
+ assets.Reverse();
+ foreach (string asset in assets)
+ {
+ // legacy support for assets that were stored as absolute paths
+ string filepath = asset.StartsWith("\\") ? Path.Combine(_environment.ContentRootPath, asset.Substring(1)) : asset;
+ if (File.Exists(filepath))
+ {
+ File.Delete(filepath);
+ if (!Directory.EnumerateFiles(Path.GetDirectoryName(filepath)).Any())
+ {
+ Directory.Delete(Path.GetDirectoryName(filepath));
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
public void UpgradeFramework()
{
string folder = Path.Combine(_environment.WebRootPath, "Framework");
diff --git a/Oqtane.Server/Infrastructure/Interfaces/IInstallationManager.cs b/Oqtane.Server/Infrastructure/Interfaces/IInstallationManager.cs
index b491987c..5c2f2853 100644
--- a/Oqtane.Server/Infrastructure/Interfaces/IInstallationManager.cs
+++ b/Oqtane.Server/Infrastructure/Interfaces/IInstallationManager.cs
@@ -2,7 +2,8 @@ namespace Oqtane.Infrastructure
{
public interface IInstallationManager
{
- void InstallPackages(string folders);
+ void InstallPackages();
+ bool UninstallPackage(string PackageName);
void UpgradeFramework();
void RestartApplication();
}
diff --git a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs
index 9574ac58..1b72d3f8 100644
--- a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs
+++ b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs
@@ -96,7 +96,14 @@ namespace Oqtane.Repository
var ids = new HashSet(moduleDefinitions.Select(item => item.ModuleDefinitionId));
foreach (var permission in permissions.Where(item => !ids.Contains(item.EntityId)))
{
- _permissions.DeletePermission(permission.PermissionId);
+ try
+ {
+ _permissions.DeletePermission(permission.PermissionId);
+ }
+ catch
+ {
+ // multi-threading can cause a race condition to occur
+ }
}
}
else
diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs
index 8ddb3c10..1188e136 100644
--- a/Oqtane.Server/Startup.cs
+++ b/Oqtane.Server/Startup.cs
@@ -174,7 +174,7 @@ namespace Oqtane
services.AddSingleton();
// install any modules or themes ( this needs to occur BEFORE the assemblies are loaded into the app domain )
- InstallationManager.InstallPackages("Modules,Themes,Packages", _env.WebRootPath, _env.ContentRootPath);
+ InstallationManager.InstallPackages(_env.WebRootPath, _env.ContentRootPath);
// register transient scoped core services
services.AddTransient();
diff --git a/Oqtane.Server/wwwroot/Packages/Oqtane.Blogs.log b/Oqtane.Server/wwwroot/Packages/Oqtane.Blogs.log
new file mode 100644
index 00000000..cbd320d1
--- /dev/null
+++ b/Oqtane.Server/wwwroot/Packages/Oqtane.Blogs.log
@@ -0,0 +1 @@
+["C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Blogs.Client.Oqtane.dll","C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Blogs.Client.Oqtane.pdb","C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Blogs.Server.Oqtane.dll","C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Blogs.Server.Oqtane.pdb","C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Blogs.Shared.Oqtane.dll","C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Blogs.Shared.Oqtane.pdb","\\wwwroot\\Modules\\Oqtane.Blogs\\Module.css","\\wwwroot\\Modules\\Oqtane.Blogs\\Module.js"]
\ No newline at end of file
diff --git a/Oqtane.Server/wwwroot/Packages/Oqtane.Database.SqlServer.log b/Oqtane.Server/wwwroot/Packages/Oqtane.Database.SqlServer.log
new file mode 100644
index 00000000..9be42acf
--- /dev/null
+++ b/Oqtane.Server/wwwroot/Packages/Oqtane.Database.SqlServer.log
@@ -0,0 +1 @@
+["C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Database.SqlServer.dll","C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Oqtane.Database.SqlServer.pdb","C:\\Users\\Shaun.Walker\\source\\repos\\sbwalker\\oqtane.framework\\Oqtane.Server\\bin\\Debug\\net5.0\\Microsoft.EntityFrameworkCore.SqlServer.dll"]
\ No newline at end of file