From 764fa4935e2ccb5cd2a9016b82f555a0f4fd9e2c Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sun, 26 Jan 2025 17:11:44 +0530 Subject: [PATCH] DnsApplicationAssemblyLoadContext: updated implementation to load managed reference DLLs too using temp files to allow update/uninstall of app at runtime on Windows. --- .../DnsApplicationAssemblyLoadContext.cs | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/DnsServerCore/Dns/Applications/DnsApplicationAssemblyLoadContext.cs b/DnsServerCore/Dns/Applications/DnsApplicationAssemblyLoadContext.cs index 0b988965..fb8e51b9 100644 --- a/DnsServerCore/Dns/Applications/DnsApplicationAssemblyLoadContext.cs +++ b/DnsServerCore/Dns/Applications/DnsApplicationAssemblyLoadContext.cs @@ -37,7 +37,7 @@ namespace DnsServerCore.Dns.Applications readonly AssemblyDependencyResolver _dependencyResolver; readonly Dictionary _loadedUnmanagedDlls = new Dictionary(); - readonly List _unmanagedDllTempPaths = new List(); + readonly List _dllTempPaths = new List(); #endregion @@ -50,11 +50,11 @@ namespace DnsServerCore.Dns.Applications Unloading += delegate (AssemblyLoadContext obj) { - foreach (string unmanagedDllTempPath in _unmanagedDllTempPaths) + foreach (string dllTempPath in _dllTempPaths) { try { - File.Delete(unmanagedDllTempPath); + File.Delete(dllTempPath); } catch { } @@ -116,7 +116,12 @@ namespace DnsServerCore.Dns.Applications { string resolvedPath = _dependencyResolver.ResolveAssemblyToPath(assemblyName); if (!string.IsNullOrEmpty(resolvedPath) && File.Exists(resolvedPath)) - return LoadFromAssemblyPath(resolvedPath); + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return LoadFromAssemblyPath(GetTempDllFile(resolvedPath)); + else + return LoadFromAssemblyPath(resolvedPath); + } } foreach (Assembly loadedAssembly in Default.Assemblies) @@ -199,26 +204,9 @@ namespace DnsServerCore.Dns.Applications //load the unmanaged DLL if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - //copy unmanaged dll into temp file for loading to allow uninstalling/updating app at runtime. - string tempPath = Path.GetTempFileName(); - - using (FileStream srcFile = new FileStream(unmanagedDllPath, FileMode.Open, FileAccess.Read)) - { - using (FileStream dstFile = new FileStream(tempPath, FileMode.Create, FileAccess.Write)) - { - srcFile.CopyTo(dstFile); - } - } - - _unmanagedDllTempPaths.Add(tempPath); - - value = LoadUnmanagedDllFromPath(tempPath); - } + value = LoadUnmanagedDllFromPath(GetTempDllFile(unmanagedDllPath)); else - { value = LoadUnmanagedDllFromPath(unmanagedDllPath); - } _loadedUnmanagedDlls.Add(unmanagedDllPath.ToLowerInvariant(), value); } @@ -231,6 +219,24 @@ namespace DnsServerCore.Dns.Applications #region private + private string GetTempDllFile(string dllFile) + { + //copy dll into temp file for loading to allow uninstalling/updating app at runtime. + string tempPath = Path.GetTempFileName(); + + using (FileStream srcFile = new FileStream(dllFile, FileMode.Open, FileAccess.Read)) + { + using (FileStream dstFile = new FileStream(tempPath, FileMode.Create, FileAccess.Write)) + { + srcFile.CopyTo(dstFile); + } + } + + _dllTempPaths.Add(tempPath); + + return tempPath; + } + private string FindUnmanagedDllPath(string unmanagedDllName, string runtime, string[] prefixes, string[] extensions) { foreach (string prefix in prefixes)