diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj
index 5f0cfe6fd..b190fa0a4 100644
--- a/src/Artemis.Core/Artemis.Core.csproj
+++ b/src/Artemis.Core/Artemis.Core.csproj
@@ -113,6 +113,7 @@
+
diff --git a/src/Artemis.Core/Extensions/DirectoryInfoExtensions.cs b/src/Artemis.Core/Extensions/DirectoryInfoExtensions.cs
new file mode 100644
index 000000000..6b3a62785
--- /dev/null
+++ b/src/Artemis.Core/Extensions/DirectoryInfoExtensions.cs
@@ -0,0 +1,15 @@
+using System.IO;
+
+namespace Artemis.Core.Extensions
+{
+ public static class DirectoryInfoExtensions
+ {
+ public static void CopyFilesRecursively(this DirectoryInfo source, DirectoryInfo target)
+ {
+ foreach (var dir in source.GetDirectories())
+ CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
+ foreach (var file in source.GetFiles())
+ file.CopyTo(Path.Combine(target.FullName, file.Name));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs
index 19915612e..c56789132 100644
--- a/src/Artemis.Core/Services/CoreService.cs
+++ b/src/Artemis.Core/Services/CoreService.cs
@@ -39,6 +39,7 @@ namespace Artemis.Core.Services
throw new ArtemisCoreException("Cannot initialize the core as it is already initialized.");
// Initialize the services
+ await Task.Run(() => _pluginService.CopyBuiltInPlugins());
await Task.Run(() => _pluginService.LoadPlugins());
OnInitialized();
diff --git a/src/Artemis.Core/Services/Interfaces/IPluginService.cs b/src/Artemis.Core/Services/Interfaces/IPluginService.cs
index c51cd70db..50b904711 100644
--- a/src/Artemis.Core/Services/Interfaces/IPluginService.cs
+++ b/src/Artemis.Core/Services/Interfaces/IPluginService.cs
@@ -13,6 +13,12 @@ namespace Artemis.Core.Services.Interfaces
///
bool LoadingPlugins { get; }
+ ///
+ /// Copy built-in plugins from the executable directory to the plugins directory if the version is higher
+ /// (higher or equal if compiled as debug)
+ ///
+ void CopyBuiltInPlugins();
+
///
/// Loads all installed plugins. If plugins already loaded this will reload them all
///
diff --git a/src/Artemis.Core/Services/PluginService.cs b/src/Artemis.Core/Services/PluginService.cs
index c7e8c15bb..77407c8ac 100644
--- a/src/Artemis.Core/Services/PluginService.cs
+++ b/src/Artemis.Core/Services/PluginService.cs
@@ -5,6 +5,7 @@ using System.Linq;
using AppDomainToolkit;
using Artemis.Core.Events;
using Artemis.Core.Exceptions;
+using Artemis.Core.Extensions;
using Artemis.Core.Plugins.Abstract;
using Artemis.Core.Plugins.Exceptions;
using Artemis.Core.Plugins.Models;
@@ -30,6 +31,7 @@ namespace Artemis.Core.Services
_kernel = kernel;
_plugins = new List();
+ // Ensure the plugins directory exists
if (!Directory.Exists(Constants.DataFolder + "plugins"))
Directory.CreateDirectory(Constants.DataFolder + "plugins");
}
@@ -37,6 +39,54 @@ namespace Artemis.Core.Services
///
public bool LoadingPlugins { get; private set; }
+ ///
+ public void CopyBuiltInPlugins()
+ {
+ var pluginDirectory = new DirectoryInfo(Path.Combine(Constants.DataFolder, "plugins"));
+
+ // Iterate built-in plugins
+ var varBuiltInPluginDirectory = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "Plugins"));
+ foreach (var subDirectory in varBuiltInPluginDirectory.EnumerateDirectories())
+ {
+ // Load the metadata
+ var builtInMetadataFile = Path.Combine(subDirectory.FullName, "plugin.json");
+ if (!File.Exists(builtInMetadataFile))
+ throw new ArtemisPluginException("Couldn't find the built-in plugins metadata file at " + builtInMetadataFile);
+
+ var builtInPluginInfo = JsonConvert.DeserializeObject(File.ReadAllText(builtInMetadataFile));
+
+ // Find the matching plugin in the plugin folder
+ var match = pluginDirectory.EnumerateDirectories().FirstOrDefault(d => d.Name == subDirectory.Name);
+ if (match == null)
+ CopyBuiltInPlugin(subDirectory);
+ else
+ {
+ var metadataFile = Path.Combine(match.FullName, "plugin.json");
+ if (!File.Exists(metadataFile))
+ CopyBuiltInPlugin(subDirectory);
+ else
+ {
+ try
+ {
+ // Compare versions, copy if the same when debugging
+ var pluginInfo = JsonConvert.DeserializeObject(File.ReadAllText(builtInMetadataFile));
+ #if DEBUG
+ if (builtInPluginInfo.Version >= pluginInfo.Version)
+ CopyBuiltInPlugin(subDirectory);
+ #else
+ if (builtInPluginInfo.Version > pluginInfo.Version)
+ CopyBuiltInPlugin(subDirectory);
+ #endif
+ }
+ catch (Exception e)
+ {
+ throw new ArtemisPluginException("Failed read plugin metadata needed to install built-in plugin", e);
+ }
+ }
+ }
+ }
+ }
+
///
public void LoadPlugins()
{
@@ -54,8 +104,8 @@ namespace Artemis.Core.Services
_childKernel = new ChildKernel(_kernel);
// Load the plugin assemblies into the plugin context
- var directory = new DirectoryInfo(Path.Combine(Constants.DataFolder, "plugins"));
- foreach (var subDirectory in directory.EnumerateDirectories())
+ var pluginDirectory = new DirectoryInfo(Path.Combine(Constants.DataFolder, "plugins"));
+ foreach (var subDirectory in pluginDirectory.EnumerateDirectories())
{
try
{
@@ -236,6 +286,17 @@ namespace Artemis.Core.Services
UnloadPlugins();
}
+ private static void CopyBuiltInPlugin(DirectoryInfo builtInPluginDirectory)
+ {
+ var pluginDirectory = new DirectoryInfo(Path.Combine(Constants.DataFolder, "plugins", builtInPluginDirectory.Name));
+
+ // Remove the old directory if it exists
+ if (Directory.Exists(pluginDirectory.FullName))
+ Directory.Delete(pluginDirectory.FullName, true);
+ Directory.CreateDirectory(pluginDirectory.FullName);
+
+ builtInPluginDirectory.CopyFilesRecursively(pluginDirectory);
+ }
#region Events
diff --git a/src/Artemis.Plugins.Devices.Corsair/Artemis.Plugins.Devices.Corsair.csproj b/src/Artemis.Plugins.Devices.Corsair/Artemis.Plugins.Devices.Corsair.csproj
index 1f0cb4ff4..73e493530 100644
--- a/src/Artemis.Plugins.Devices.Corsair/Artemis.Plugins.Devices.Corsair.csproj
+++ b/src/Artemis.Plugins.Devices.Corsair/Artemis.Plugins.Devices.Corsair.csproj
@@ -73,7 +73,7 @@
- (robocopy $(TargetDir) %25ProgramData%25\Artemis\plugins\$(ProjectName) /E /NFL /NDL /NJH /NJS /nc /ns /np) ^& IF %25ERRORLEVEL%25 LEQ 4 exit /B 0
+ (robocopy $(TargetDir) $(SolutionDir)\Artemis.UI\$(OutDir)\Plugins\$(ProjectName) /E /NFL /NDL /NJH /NJS /nc /ns /np) ^& IF %25ERRORLEVEL%25 LEQ 4 exit /B 0
diff --git a/src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerTypes.Brush.csproj b/src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerTypes.Brush.csproj
index 8445ba521..f59eb32e7 100644
--- a/src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerTypes.Brush.csproj
+++ b/src/Artemis.Plugins.LayerTypes.Brush/Artemis.Plugins.LayerTypes.Brush.csproj
@@ -86,6 +86,6 @@
- (robocopy $(TargetDir) %25ProgramData%25\Artemis\plugins\$(ProjectName) /E /NFL /NDL /NJH /NJS /nc /ns /np) ^& IF %25ERRORLEVEL%25 LEQ 4 exit /B 0
+ (robocopy $(TargetDir) $(SolutionDir)\Artemis.UI\$(OutDir)\Plugins\$(ProjectName) /E /NFL /NDL /NJH /NJS /nc /ns /np) ^& IF %25ERRORLEVEL%25 LEQ 4 exit /B 0
\ No newline at end of file
diff --git a/src/Artemis.Plugins.Modules.General/Artemis.Plugins.Modules.General.csproj b/src/Artemis.Plugins.Modules.General/Artemis.Plugins.Modules.General.csproj
index 9e4e5cd89..4978e43f1 100644
--- a/src/Artemis.Plugins.Modules.General/Artemis.Plugins.Modules.General.csproj
+++ b/src/Artemis.Plugins.Modules.General/Artemis.Plugins.Modules.General.csproj
@@ -95,6 +95,6 @@
- (robocopy $(TargetDir) %25ProgramData%25\Artemis\plugins\$(ProjectName) /E /NFL /NDL /NJH /NJS /nc /ns /np) ^& IF %25ERRORLEVEL%25 LEQ 4 exit /B 0
+ (robocopy $(TargetDir) $(SolutionDir)\Artemis.UI\$(OutDir)\Plugins\$(ProjectName) /E /NFL /NDL /NJH /NJS /nc /ns /np) ^& IF %25ERRORLEVEL%25 LEQ 4 exit /B 0
\ No newline at end of file
diff --git a/src/Artemis.Storage/StorageContext.cs b/src/Artemis.Storage/StorageContext.cs
index 8af00a422..eae7928be 100644
--- a/src/Artemis.Storage/StorageContext.cs
+++ b/src/Artemis.Storage/StorageContext.cs
@@ -1,5 +1,5 @@
-using System.IO;
-using System.Reflection;
+using System;
+using System.IO;
using Artemis.Storage.Entities;
using Microsoft.EntityFrameworkCore;
using SQLitePCL;
@@ -14,12 +14,12 @@ namespace Artemis.Storage
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
-// var dbLocation = @"C:\Repos\Artemis\src\Artemis.Storage\Storage.db";
+ // ReSharper disable once RedundantAssignment - Used if not debugging
+ var dbLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Artemis\\Storage.db");
#if DEBUG
- var dbLocation = Path.GetFullPath(Path.Combine(Assembly.GetEntryAssembly().Location, @"..\..\..\..\Artemis.Storage\Storage.db"));
- #else
- var dbLocation = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\Artemis\\Storage.db";
+ dbLocation = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @"..\..\..\..\Artemis.Storage\Storage.db"));
#endif
+
optionsBuilder.UseSqlite("Data Source=" + dbLocation);
// Requires Microsoft.Data.Sqlite in the startup project