aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs12
-rw-r--r--Emby.Server.Implementations/IStartupOptions.cs10
-rw-r--r--Emby.Server.Implementations/Plugins/PluginLoadContext.cs33
-rw-r--r--Emby.Server.Implementations/Plugins/PluginManager.cs18
4 files changed, 51 insertions, 22 deletions
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 7b3d07dfc..3db48e42f 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -193,11 +193,6 @@ namespace Emby.Server.Implementations
/// </summary>
private string PublishedServerUrl => _startupConfig[AddressOverrideKey];
- /// <summary>
- /// Gets a value indicating whether this instance can self restart.
- /// </summary>
- public bool CanSelfRestart => _startupOptions.RestartPath is not null;
-
public bool CoreStartupHasCompleted { get; private set; }
public virtual bool CanLaunchWebBrowser
@@ -935,17 +930,13 @@ namespace Emby.Server.Implementations
/// </summary>
public void Restart()
{
- if (!CanSelfRestart)
- {
- throw new PlatformNotSupportedException("The server is unable to self-restart. Please restart manually.");
- }
-
if (IsShuttingDown)
{
return;
}
IsShuttingDown = true;
+ _pluginManager.UnloadAssemblies();
Task.Run(async () =>
{
@@ -1047,7 +1038,6 @@ namespace Emby.Server.Implementations
CachePath = ApplicationPaths.CachePath,
OperatingSystem = MediaBrowser.Common.System.OperatingSystem.Id.ToString(),
OperatingSystemDisplayName = MediaBrowser.Common.System.OperatingSystem.Name,
- CanSelfRestart = CanSelfRestart,
CanLaunchWebBrowser = CanLaunchWebBrowser,
TranscodingTempPath = ConfigurationManager.GetTranscodePath(),
ServerName = FriendlyName,
diff --git a/Emby.Server.Implementations/IStartupOptions.cs b/Emby.Server.Implementations/IStartupOptions.cs
index 3769ae4dd..b7bcaace1 100644
--- a/Emby.Server.Implementations/IStartupOptions.cs
+++ b/Emby.Server.Implementations/IStartupOptions.cs
@@ -21,16 +21,6 @@ namespace Emby.Server.Implementations
string? PackageName { get; }
/// <summary>
- /// Gets the value of the --restartpath command line option.
- /// </summary>
- string? RestartPath { get; }
-
- /// <summary>
- /// Gets the value of the --restartargs command line option.
- /// </summary>
- string? RestartArgs { get; }
-
- /// <summary>
/// Gets the value of the --published-server-url command line option.
/// </summary>
string? PublishedServerUrl { get; }
diff --git a/Emby.Server.Implementations/Plugins/PluginLoadContext.cs b/Emby.Server.Implementations/Plugins/PluginLoadContext.cs
new file mode 100644
index 000000000..d04e9cf68
--- /dev/null
+++ b/Emby.Server.Implementations/Plugins/PluginLoadContext.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.Loader;
+
+namespace Emby.Server.Implementations.Plugins;
+
+/// <summary>
+/// A custom <see cref="AssemblyLoadContext"/> for loading Jellyfin plugins.
+/// </summary>
+public class PluginLoadContext : AssemblyLoadContext
+{
+ private readonly AssemblyDependencyResolver _resolver;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PluginLoadContext"/> class.
+ /// </summary>
+ /// <param name="path">The path of the plugin assembly.</param>
+ public PluginLoadContext(string path) : base(true)
+ {
+ _resolver = new AssemblyDependencyResolver(path);
+ }
+
+ /// <inheritdoc />
+ protected override Assembly? Load(AssemblyName assemblyName)
+ {
+ var assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
+ if (assemblyPath is not null)
+ {
+ return LoadFromAssemblyPath(assemblyPath);
+ }
+
+ return null;
+ }
+}
diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs
index 14e7c2269..f2212f4dc 100644
--- a/Emby.Server.Implementations/Plugins/PluginManager.cs
+++ b/Emby.Server.Implementations/Plugins/PluginManager.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
+using System.Runtime.Loader;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
@@ -30,6 +31,7 @@ namespace Emby.Server.Implementations.Plugins
{
private readonly string _pluginsPath;
private readonly Version _appVersion;
+ private readonly List<AssemblyLoadContext> _assemblyLoadContexts;
private readonly JsonSerializerOptions _jsonOptions;
private readonly ILogger<PluginManager> _logger;
private readonly IApplicationHost _appHost;
@@ -76,6 +78,8 @@ namespace Emby.Server.Implementations.Plugins
_appHost = appHost;
_minimumVersion = new Version(0, 0, 0, 1);
_plugins = Directory.Exists(_pluginsPath) ? DiscoverPlugins().ToList() : new List<LocalPlugin>();
+
+ _assemblyLoadContexts = new List<AssemblyLoadContext>();
}
private IHttpClientFactory HttpClientFactory
@@ -124,7 +128,10 @@ namespace Emby.Server.Implementations.Plugins
Assembly assembly;
try
{
- assembly = Assembly.LoadFrom(file);
+ var assemblyLoadContext = new PluginLoadContext(file);
+ _assemblyLoadContexts.Add(assemblyLoadContext);
+
+ assembly = assemblyLoadContext.LoadFromAssemblyPath(file);
// Load all required types to verify that the plugin will load
assembly.GetTypes();
@@ -156,6 +163,15 @@ namespace Emby.Server.Implementations.Plugins
}
}
+ /// <inheritdoc />
+ public void UnloadAssemblies()
+ {
+ foreach (var assemblyLoadContext in _assemblyLoadContexts)
+ {
+ assemblyLoadContext.Unload();
+ }
+ }
+
/// <summary>
/// Creates all the plugin instances.
/// </summary>