clean up pdb files on client, hash assembly file names
This commit is contained in:
parent
c0f4069a9b
commit
45df729711
|
@ -117,6 +117,7 @@ namespace Oqtane.Client
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await interop.RemoveIndexedDBItem(file);
|
await interop.RemoveIndexedDBItem(file);
|
||||||
|
await interop.RemoveIndexedDBItem(file.Replace(".dll", ".pdb"));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,7 +127,10 @@ public static class MauiProgram
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.Delete(Path.Combine(folder, file));
|
foreach (var path in Directory.EnumerateFiles(folder, Path.GetFileNameWithoutExtension(file) + ".*"))
|
||||||
|
{
|
||||||
|
File.Delete(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -159,11 +162,6 @@ public static class MauiProgram
|
||||||
// save assembly to local folder
|
// save assembly to local folder
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int subfolder = entry.FullName.IndexOf('/');
|
|
||||||
if (subfolder != -1 && !Directory.Exists(Path.Combine(folder, entry.FullName.Substring(0, subfolder))))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(Path.Combine(folder, entry.FullName.Substring(0, subfolder)));
|
|
||||||
}
|
|
||||||
using var stream = File.Create(Path.Combine(folder, entry.FullName));
|
using var stream = File.Create(Path.Combine(folder, entry.FullName));
|
||||||
stream.Write(file, 0, file.Length);
|
stream.Write(file, 0, file.Length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,10 +103,7 @@ namespace Oqtane.Controllers
|
||||||
[HttpGet("list")]
|
[HttpGet("list")]
|
||||||
public List<string> List()
|
public List<string> List()
|
||||||
{
|
{
|
||||||
return _cache.GetOrCreate("assemblieslist", entry =>
|
return GetAssemblyList().Select(item => item.HashedName).ToList();
|
||||||
{
|
|
||||||
return GetAssemblyList();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET api/<controller>/load?list=x,y
|
// GET api/<controller>/load?list=x,y
|
||||||
|
@ -116,81 +113,90 @@ namespace Oqtane.Controllers
|
||||||
return File(GetAssemblies(list), System.Net.Mime.MediaTypeNames.Application.Octet, "oqtane.dll");
|
return File(GetAssemblies(list), System.Net.Mime.MediaTypeNames.Application.Octet, "oqtane.dll");
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> GetAssemblyList()
|
private List<ClientAssembly> GetAssemblyList()
|
||||||
{
|
{
|
||||||
// get list of assemblies which should be downloaded to client
|
return _cache.GetOrCreate("assemblieslist", entry =>
|
||||||
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
|
||||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
|
||||||
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
|
||||||
|
|
||||||
// include version numbers
|
|
||||||
for (int i = 0; i < list.Count; i++)
|
|
||||||
{
|
{
|
||||||
list[i] = Path.GetFileName(AddFileDate(Path.Combine(binFolder, list[i] + ".dll")));
|
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
}
|
var assemblyList = new List<ClientAssembly>();
|
||||||
|
|
||||||
// insert satellite assemblies at beginning of list
|
// get list of assemblies which should be downloaded to client
|
||||||
foreach (var culture in _localizationManager.GetInstalledCultures())
|
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
||||||
{
|
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
||||||
var assembliesFolderPath = Path.Combine(binFolder, culture);
|
|
||||||
if (culture == Constants.DefaultCulture)
|
// populate assemblies
|
||||||
|
for (int i = 0; i < list.Count; i++)
|
||||||
{
|
{
|
||||||
continue;
|
assemblyList.Add(new ClientAssembly(Path.Combine(binFolder, list[i] + ".dll")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Directory.Exists(assembliesFolderPath))
|
// insert satellite assemblies at beginning of list
|
||||||
|
foreach (var culture in _localizationManager.GetInstalledCultures())
|
||||||
{
|
{
|
||||||
foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath))
|
var assembliesFolderPath = Path.Combine(binFolder, culture);
|
||||||
|
if (culture == Constants.DefaultCulture)
|
||||||
{
|
{
|
||||||
list.Insert(0, culture + "/" + Path.GetFileName(AddFileDate(resourceFile)));
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Directory.Exists(assembliesFolderPath))
|
||||||
|
{
|
||||||
|
foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath))
|
||||||
|
{
|
||||||
|
assemblyList.Insert(0, new ClientAssembly(resourceFile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, $"The Satellite Assembly Folder For {culture} Does Not Exist"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_filelogger.LogError(Utilities.LogMessage(this, $"The Satellite Assembly Folder For {culture} Does Not Exist"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert module and theme dependencies at beginning of list
|
// insert module and theme dependencies at beginning of list
|
||||||
foreach (var assembly in assemblies)
|
foreach (var assembly in assemblies)
|
||||||
{
|
|
||||||
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModule))))
|
|
||||||
{
|
{
|
||||||
var instance = Activator.CreateInstance(type) as IModule;
|
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModule))))
|
||||||
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
|
||||||
{
|
{
|
||||||
var path = Path.Combine(binFolder, name + ".dll");
|
var instance = Activator.CreateInstance(type) as IModule;
|
||||||
if (System.IO.File.Exists(path))
|
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Reverse())
|
||||||
{
|
{
|
||||||
path = Path.GetFileName(AddFileDate(path));
|
var filepath = Path.Combine(binFolder, name + ".dll");
|
||||||
if (!list.Contains(path)) list.Insert(0, path);
|
if (System.IO.File.Exists(filepath))
|
||||||
|
{
|
||||||
|
if (!assemblyList.Exists(item => item.FilePath == filepath))
|
||||||
|
{
|
||||||
|
assemblyList.Insert(0, new ClientAssembly(filepath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, $"Module {instance.ModuleDefinition.ModuleDefinitionName} Dependency {name}.dll Does Not Exist"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme))))
|
||||||
|
{
|
||||||
|
var instance = Activator.CreateInstance(type) as ITheme;
|
||||||
|
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Reverse())
|
||||||
{
|
{
|
||||||
_filelogger.LogError(Utilities.LogMessage(this, $"Module {instance.ModuleDefinition.ModuleDefinitionName} Dependency {name}.dll Does Not Exist"));
|
var filepath = Path.Combine(binFolder, name + ".dll");
|
||||||
|
if (System.IO.File.Exists(filepath))
|
||||||
|
{
|
||||||
|
if (!assemblyList.Exists(item => item.FilePath == filepath))
|
||||||
|
{
|
||||||
|
assemblyList.Insert(0, new ClientAssembly(filepath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_filelogger.LogError(Utilities.LogMessage(this, $"Theme {instance.Theme.ThemeName} Dependency {name}.dll Does Not Exist"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme))))
|
|
||||||
{
|
|
||||||
var instance = Activator.CreateInstance(type) as ITheme;
|
|
||||||
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
|
||||||
{
|
|
||||||
var path = Path.Combine(binFolder, name + ".dll");
|
|
||||||
if (System.IO.File.Exists(path))
|
|
||||||
{
|
|
||||||
path = Path.GetFileName(AddFileDate(path));
|
|
||||||
if (!list.Contains(path)) list.Insert(0, path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_filelogger.LogError(Utilities.LogMessage(this, $"Theme {instance.Theme.ThemeName} Dependency {name}.dll Does Not Exist"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
return assemblyList;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] GetAssemblies(string list)
|
private byte[] GetAssemblies(string list)
|
||||||
|
@ -213,14 +219,11 @@ namespace Oqtane.Controllers
|
||||||
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
|
|
||||||
// get list of assemblies which should be downloaded to client
|
// get list of assemblies which should be downloaded to client
|
||||||
List<string> assemblies;
|
List<ClientAssembly> assemblies = GetAssemblyList();
|
||||||
if (list == "*")
|
if (list != "*")
|
||||||
{
|
{
|
||||||
assemblies = GetAssemblyList();
|
var filter = list.Split(',').ToList();
|
||||||
}
|
assemblies.RemoveAll(item => !filter.Contains(item.HashedName));
|
||||||
else
|
|
||||||
{
|
|
||||||
assemblies = list.Split(',').ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create zip file containing assemblies and debug symbols
|
// create zip file containing assemblies and debug symbols
|
||||||
|
@ -228,22 +231,21 @@ namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
||||||
{
|
{
|
||||||
foreach (string file in assemblies)
|
foreach (var assembly in assemblies)
|
||||||
{
|
{
|
||||||
var filename = RemoveFileDate(file);
|
if (System.IO.File.Exists(assembly.FilePath))
|
||||||
if (System.IO.File.Exists(Path.Combine(binFolder, filename)))
|
|
||||||
{
|
{
|
||||||
using (var filestream = new FileStream(Path.Combine(binFolder, filename), FileMode.Open, FileAccess.Read))
|
using (var filestream = new FileStream(assembly.FilePath, FileMode.Open, FileAccess.Read))
|
||||||
using (var entrystream = archive.CreateEntry(file).Open())
|
using (var entrystream = archive.CreateEntry(assembly.HashedName).Open())
|
||||||
{
|
{
|
||||||
filestream.CopyTo(entrystream);
|
filestream.CopyTo(entrystream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filename = filename.Replace(".dll", ".pdb");
|
var pdb = assembly.FilePath.Replace(".dll", ".pdb");
|
||||||
if (System.IO.File.Exists(Path.Combine(binFolder, filename)))
|
if (System.IO.File.Exists(pdb))
|
||||||
{
|
{
|
||||||
using (var filestream = new FileStream(Path.Combine(binFolder, filename), FileMode.Open, FileAccess.Read))
|
using (var filestream = new FileStream(pdb, FileMode.Open, FileAccess.Read))
|
||||||
using (var entrystream = archive.CreateEntry(file.Replace(".dll", ".pdb")).Open())
|
using (var entrystream = archive.CreateEntry(assembly.HashedName.Replace(".dll", ".pdb")).Open())
|
||||||
{
|
{
|
||||||
filestream.CopyTo(entrystream);
|
filestream.CopyTo(entrystream);
|
||||||
}
|
}
|
||||||
|
@ -255,18 +257,6 @@ namespace Oqtane.Controllers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string AddFileDate(string filepath)
|
|
||||||
{
|
|
||||||
DateTime lastwritetime = System.IO.File.GetLastWriteTime(filepath);
|
|
||||||
return Path.GetFileNameWithoutExtension(filepath) + "." + lastwritetime.ToString("yyyyMMddHHmmss") + Path.GetExtension(filepath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string RemoveFileDate(string filepath)
|
|
||||||
{
|
|
||||||
var segments = filepath.Split(".");
|
|
||||||
return string.Join(".", segments, 0, segments.Length - 2) + Path.GetExtension(filepath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task RegisterContact(string email)
|
private async Task RegisterContact(string email)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -292,5 +282,38 @@ namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
await RegisterContact(email);
|
await RegisterContact(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct ClientAssembly
|
||||||
|
{
|
||||||
|
public ClientAssembly(string filepath)
|
||||||
|
{
|
||||||
|
FilePath = filepath;
|
||||||
|
DateTime lastwritetime = System.IO.File.GetLastWriteTime(filepath);
|
||||||
|
HashedName = GetDeterministicHashCode(filepath).ToString("X8") + "." + lastwritetime.ToString("yyyyMMddHHmmss") + Path.GetExtension(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FilePath { get; private set; }
|
||||||
|
public string HashedName { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetDeterministicHashCode(string value)
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
int hash1 = (5381 << 16) + 5381;
|
||||||
|
int hash2 = hash1;
|
||||||
|
|
||||||
|
for (int i = 0; i < value.Length; i += 2)
|
||||||
|
{
|
||||||
|
hash1 = ((hash1 << 5) + hash1) ^ value[i];
|
||||||
|
if (i == value.Length - 1)
|
||||||
|
break;
|
||||||
|
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash1 + (hash2 * 1566083941);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user