diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs
index b1bab8cdd..4eed79c4c 100644
--- a/Emby.Server.Implementations/Updates/InstallationManager.cs
+++ b/Emby.Server.Implementations/Updates/InstallationManager.cs
@@ -406,6 +406,12 @@ namespace Emby.Server.Implementations.Updates
/// The plugin.
public void UninstallPlugin(IPlugin plugin)
{
+ if (!plugin.CanUninstall)
+ {
+ _logger.LogWarning("Attempt to delete non removable plugin {0}, ignoring request", plugin.Name);
+ return;
+ }
+
plugin.OnUninstalling();
// Remove it the quick way for now
diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs
index 9e4a360c3..f10a1918f 100644
--- a/MediaBrowser.Common/Plugins/BasePlugin.cs
+++ b/MediaBrowser.Common/Plugins/BasePlugin.cs
@@ -2,6 +2,7 @@
using System;
using System.IO;
+using System.Reflection;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Serialization;
@@ -49,6 +50,12 @@ namespace MediaBrowser.Common.Plugins
/// The data folder path.
public string DataFolderPath { get; private set; }
+ ///
+ /// Gets a value indicating whether the plugin can be uninstalled.
+ ///
+ public bool CanUninstall => !Path.GetDirectoryName(AssemblyFilePath)
+ .Equals(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), StringComparison.InvariantCulture);
+
///
/// Gets the plugin info.
///
@@ -60,7 +67,8 @@ namespace MediaBrowser.Common.Plugins
Name = Name,
Version = Version.ToString(),
Description = Description,
- Id = Id.ToString()
+ Id = Id.ToString(),
+ CanUninstall = CanUninstall
};
return info;
diff --git a/MediaBrowser.Common/Plugins/IPlugin.cs b/MediaBrowser.Common/Plugins/IPlugin.cs
index d34820961..7bd37d210 100644
--- a/MediaBrowser.Common/Plugins/IPlugin.cs
+++ b/MediaBrowser.Common/Plugins/IPlugin.cs
@@ -40,6 +40,11 @@ namespace MediaBrowser.Common.Plugins
/// The assembly file path.
string AssemblyFilePath { get; }
+ ///
+ /// Gets a value indicating whether the plugin can be uninstalled.
+ ///
+ bool CanUninstall { get; }
+
///
/// Gets the full path to the data folder, where the plugin can store any miscellaneous files needed.
///
diff --git a/MediaBrowser.Model/Plugins/PluginInfo.cs b/MediaBrowser.Model/Plugins/PluginInfo.cs
index c13f1a89f..dd215192f 100644
--- a/MediaBrowser.Model/Plugins/PluginInfo.cs
+++ b/MediaBrowser.Model/Plugins/PluginInfo.cs
@@ -35,6 +35,12 @@ namespace MediaBrowser.Model.Plugins
///
/// The unique id.
public string Id { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the plugin can be uninstalled.
+ ///
+ public bool CanUninstall { get; set; }
+
///
/// Gets or sets the image URL.
///