mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 09:43:46 +00:00
Plugin settings - Restart Artemis for plugins that require admin rights
Setup wizard - Restart Artemis device providers that require admin rights Setup wizard - Gracefully handle errors during device provider enable Profile editor - Select a valid default brush on clean installs
This commit is contained in:
parent
b917f36978
commit
985a94dbaf
@ -71,7 +71,7 @@ namespace Artemis.Core.Services
|
|||||||
Plugin ImportPlugin(string fileName);
|
Plugin ImportPlugin(string fileName);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads and permanently removes the provided plugin
|
/// Unloads and permanently removes the provided plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plugin">The plugin to remove</param>
|
/// <param name="plugin">The plugin to remove</param>
|
||||||
void RemovePlugin(Plugin plugin);
|
void RemovePlugin(Plugin plugin);
|
||||||
@ -127,6 +127,13 @@ namespace Artemis.Core.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
DeviceProvider GetDeviceProviderByDevice(IRGBDevice device);
|
DeviceProvider GetDeviceProviderByDevice(IRGBDevice device);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queues an action for the provided plugin for the next time Artemis starts, before plugins are loaded
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin">The plugin to queue the action for</param>
|
||||||
|
/// <param name="pluginAction">The action to take</param>
|
||||||
|
void QueuePluginAction(Plugin plugin, PluginManagementAction pluginAction);
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -27,6 +27,7 @@ namespace Artemis.Core.Services
|
|||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IPluginRepository _pluginRepository;
|
private readonly IPluginRepository _pluginRepository;
|
||||||
private readonly List<Plugin> _plugins;
|
private readonly List<Plugin> _plugins;
|
||||||
|
private bool _isElevated;
|
||||||
|
|
||||||
public PluginManagementService(IKernel kernel, ILogger logger, IPluginRepository pluginRepository)
|
public PluginManagementService(IKernel kernel, ILogger logger, IPluginRepository pluginRepository)
|
||||||
{
|
{
|
||||||
@ -34,6 +35,8 @@ namespace Artemis.Core.Services
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
_pluginRepository = pluginRepository;
|
_pluginRepository = pluginRepository;
|
||||||
_plugins = new List<Plugin>();
|
_plugins = new List<Plugin>();
|
||||||
|
|
||||||
|
ProcessQueuedActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CopyBuiltInPlugin(FileInfo zipFileInfo, ZipArchive zipArchive)
|
private void CopyBuiltInPlugin(FileInfo zipFileInfo, ZipArchive zipArchive)
|
||||||
@ -181,6 +184,7 @@ namespace Artemis.Core.Services
|
|||||||
if (LoadingPlugins)
|
if (LoadingPlugins)
|
||||||
throw new ArtemisCoreException("Cannot load plugins while a previous load hasn't been completed yet.");
|
throw new ArtemisCoreException("Cannot load plugins while a previous load hasn't been completed yet.");
|
||||||
|
|
||||||
|
_isElevated = isElevated;
|
||||||
LoadingPlugins = true;
|
LoadingPlugins = true;
|
||||||
|
|
||||||
// Unload all currently loaded plugins first
|
// Unload all currently loaded plugins first
|
||||||
@ -203,7 +207,7 @@ namespace Artemis.Core.Services
|
|||||||
// ReSharper disable InconsistentlySynchronizedField - It's read-only, idc
|
// ReSharper disable InconsistentlySynchronizedField - It's read-only, idc
|
||||||
_logger.Debug("Loaded {count} plugin(s)", _plugins.Count);
|
_logger.Debug("Loaded {count} plugin(s)", _plugins.Count);
|
||||||
|
|
||||||
bool adminRequired = _plugins.Any(p => p.Entity.IsEnabled && p.Info.RequiresAdmin);
|
bool adminRequired = _plugins.Any(p => p.Info.RequiresAdmin && p.Entity.IsEnabled && p.Entity.Features.Any(f => f.IsEnabled));
|
||||||
if (!isElevated && adminRequired)
|
if (!isElevated && adminRequired)
|
||||||
{
|
{
|
||||||
_logger.Information("Restarting because one or more plugins requires elevation");
|
_logger.Information("Restarting because one or more plugins requires elevation");
|
||||||
@ -336,6 +340,19 @@ namespace Artemis.Core.Services
|
|||||||
if (plugin.Assembly == null)
|
if (plugin.Assembly == null)
|
||||||
throw new ArtemisPluginException(plugin, "Cannot enable a plugin that hasn't successfully been loaded");
|
throw new ArtemisPluginException(plugin, "Cannot enable a plugin that hasn't successfully been loaded");
|
||||||
|
|
||||||
|
if (plugin.Info.RequiresAdmin && plugin.Entity.Features.Any(f => f.IsEnabled) && !_isElevated)
|
||||||
|
{
|
||||||
|
if (!saveState)
|
||||||
|
throw new ArtemisCoreException("Cannot enable a plugin that requires elevation without saving it's state.");
|
||||||
|
|
||||||
|
plugin.Entity.IsEnabled = true;
|
||||||
|
SavePlugin(plugin);
|
||||||
|
|
||||||
|
_logger.Information("Restarting because a newly enabled plugin requires elevation");
|
||||||
|
Utilities.Restart(true, TimeSpan.FromMilliseconds(500));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the Ninject child kernel and load the module
|
// Create the Ninject child kernel and load the module
|
||||||
plugin.Kernel = new ChildKernel(_kernel, new PluginModule(plugin));
|
plugin.Kernel = new ChildKernel(_kernel, new PluginModule(plugin));
|
||||||
OnPluginEnabling(new PluginEventArgs(plugin));
|
OnPluginEnabling(new PluginEventArgs(plugin));
|
||||||
@ -523,6 +540,21 @@ namespace Artemis.Core.Services
|
|||||||
_logger.Verbose("Enabling plugin feature {feature} - {plugin}", pluginFeature, pluginFeature.Plugin);
|
_logger.Verbose("Enabling plugin feature {feature} - {plugin}", pluginFeature, pluginFeature.Plugin);
|
||||||
|
|
||||||
OnPluginFeatureEnabling(new PluginFeatureEventArgs(pluginFeature));
|
OnPluginFeatureEnabling(new PluginFeatureEventArgs(pluginFeature));
|
||||||
|
|
||||||
|
if (pluginFeature.Plugin.Info.RequiresAdmin && !_isElevated)
|
||||||
|
{
|
||||||
|
if (!saveState)
|
||||||
|
throw new ArtemisCoreException("Cannot enable a feature that requires elevation without saving it's state.");
|
||||||
|
|
||||||
|
pluginFeature.Entity.IsEnabled = true;
|
||||||
|
pluginFeature.Plugin.Entity.IsEnabled = true;
|
||||||
|
SavePlugin(pluginFeature.Plugin);
|
||||||
|
|
||||||
|
_logger.Information("Restarting because a newly enabled feature requires elevation");
|
||||||
|
Utilities.Restart(true, TimeSpan.FromMilliseconds(500));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pluginFeature.SetEnabled(true, isAutoEnable);
|
pluginFeature.SetEnabled(true, isAutoEnable);
|
||||||
@ -586,6 +618,34 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Queued actions
|
||||||
|
|
||||||
|
public void QueuePluginAction(Plugin plugin, PluginManagementAction pluginAction)
|
||||||
|
{
|
||||||
|
List<PluginQueuedActionEntity> existing = _pluginRepository.GetQueuedActions(plugin.Guid);
|
||||||
|
if (existing.Any(e => pluginAction == PluginManagementAction.Delete && e is PluginQueuedDeleteEntity))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pluginAction == PluginManagementAction.Delete)
|
||||||
|
_pluginRepository.AddQueuedAction(new PluginQueuedDeleteEntity {PluginGuid = plugin.Guid, Directory = plugin.Directory.FullName});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessQueuedActions()
|
||||||
|
{
|
||||||
|
foreach (PluginQueuedActionEntity pluginQueuedActionEntity in _pluginRepository.GetQueuedActions())
|
||||||
|
{
|
||||||
|
if (pluginQueuedActionEntity is PluginQueuedDeleteEntity deleteAction)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(deleteAction.Directory))
|
||||||
|
Directory.Delete(deleteAction.Directory, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
_pluginRepository.RemoveQueuedAction(pluginQueuedActionEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Storage
|
#region Storage
|
||||||
|
|
||||||
private void SavePlugin(Plugin plugin)
|
private void SavePlugin(Plugin plugin)
|
||||||
@ -673,4 +733,20 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a type of plugin management action
|
||||||
|
/// </summary>
|
||||||
|
public enum PluginManagementAction
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A plugin management action that removes a plugin
|
||||||
|
/// </summary>
|
||||||
|
Delete,
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// A plugin management action that updates a plugin
|
||||||
|
// /// </summary>
|
||||||
|
// Update
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -13,4 +13,21 @@ namespace Artemis.Storage.Entities.Plugins
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a queued action for a plugin
|
||||||
|
/// </summary>
|
||||||
|
public abstract class PluginQueuedActionEntity
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public Guid PluginGuid { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a queued delete action for a plugin
|
||||||
|
/// </summary>
|
||||||
|
public class PluginQueuedDeleteEntity : PluginQueuedActionEntity
|
||||||
|
{
|
||||||
|
public string Directory { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories.Interfaces
|
namespace Artemis.Storage.Repositories.Interfaces
|
||||||
@ -8,9 +9,15 @@ namespace Artemis.Storage.Repositories.Interfaces
|
|||||||
void AddPlugin(PluginEntity pluginEntity);
|
void AddPlugin(PluginEntity pluginEntity);
|
||||||
PluginEntity GetPluginByGuid(Guid pluginGuid);
|
PluginEntity GetPluginByGuid(Guid pluginGuid);
|
||||||
void SavePlugin(PluginEntity pluginEntity);
|
void SavePlugin(PluginEntity pluginEntity);
|
||||||
|
|
||||||
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
||||||
PluginSettingEntity GetSettingByGuid(Guid pluginGuid);
|
PluginSettingEntity GetSettingByGuid(Guid pluginGuid);
|
||||||
PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
||||||
void SaveSetting(PluginSettingEntity pluginSettingEntity);
|
void SaveSetting(PluginSettingEntity pluginSettingEntity);
|
||||||
|
|
||||||
|
void AddQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity);
|
||||||
|
List<PluginQueuedActionEntity> GetQueuedActions();
|
||||||
|
List<PluginQueuedActionEntity> GetQueuedActions(Guid pluginGuid);
|
||||||
|
void RemoveQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
@ -14,6 +15,7 @@ namespace Artemis.Storage.Repositories
|
|||||||
_repository = repository;
|
_repository = repository;
|
||||||
|
|
||||||
_repository.Database.GetCollection<PluginSettingEntity>().EnsureIndex(s => new {s.Name, s.PluginGuid}, true);
|
_repository.Database.GetCollection<PluginSettingEntity>().EnsureIndex(s => new {s.Name, s.PluginGuid}, true);
|
||||||
|
_repository.Database.GetCollection<PluginQueuedActionEntity>().EnsureIndex(s => s.PluginGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddPlugin(PluginEntity pluginEntity)
|
public void AddPlugin(PluginEntity pluginEntity)
|
||||||
@ -51,5 +53,24 @@ namespace Artemis.Storage.Repositories
|
|||||||
{
|
{
|
||||||
_repository.Upsert(pluginSettingEntity);
|
_repository.Upsert(pluginSettingEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<PluginQueuedActionEntity> GetQueuedActions()
|
||||||
|
{
|
||||||
|
return _repository.Query<PluginQueuedActionEntity>().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PluginQueuedActionEntity> GetQueuedActions(Guid pluginGuid)
|
||||||
|
{
|
||||||
|
return _repository.Query<PluginQueuedActionEntity>().Where(q => q.PluginGuid == pluginGuid).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity)
|
||||||
|
{
|
||||||
|
_repository.Upsert(pluginQueuedActionEntity);
|
||||||
|
}
|
||||||
|
public void RemoveQueuedAction(PluginQueuedActionEntity pluginQueuedActionEntity)
|
||||||
|
{
|
||||||
|
_repository.Delete<PluginQueuedActionEntity>(pluginQueuedActionEntity.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ namespace Artemis.UI.Ninject.Factories
|
|||||||
public interface ISettingsVmFactory : IVmFactory
|
public interface ISettingsVmFactory : IVmFactory
|
||||||
{
|
{
|
||||||
PluginSettingsViewModel CreatePluginSettingsViewModel(Plugin plugin);
|
PluginSettingsViewModel CreatePluginSettingsViewModel(Plugin plugin);
|
||||||
PluginFeatureViewModel CreatePluginFeatureViewModel(PluginFeatureInfo pluginFeatureInfo);
|
PluginFeatureViewModel CreatePluginFeatureViewModel(PluginFeatureInfo pluginFeatureInfo, bool showShield);
|
||||||
DeviceSettingsViewModel CreateDeviceSettingsViewModel(ArtemisDevice device);
|
DeviceSettingsViewModel CreateDeviceSettingsViewModel(ArtemisDevice device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,17 +3,20 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.LayerBrushes;
|
using Artemis.Core.LayerBrushes;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.Core.Services.Core;
|
||||||
using Artemis.UI.Properties;
|
using Artemis.UI.Properties;
|
||||||
using Artemis.UI.Screens.StartupWizard;
|
using Artemis.UI.Screens.StartupWizard;
|
||||||
using Artemis.UI.Services;
|
using Artemis.UI.Services;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Artemis.UI.Utilities;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
@ -70,7 +73,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
|||||||
_defaultLayerBrushDescriptor = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
|
_defaultLayerBrushDescriptor = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
|
||||||
{
|
{
|
||||||
LayerBrushProviderId = "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba",
|
LayerBrushProviderId = "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba",
|
||||||
BrushType = "ColorBrush"
|
BrushType = "SolidBrush"
|
||||||
});
|
});
|
||||||
|
|
||||||
WebServerPortSetting = _settingsService.GetSetting("WebServer.Port", 9696);
|
WebServerPortSetting = _settingsService.GetSetting("WebServer.Port", 9696);
|
||||||
@ -306,7 +309,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
|||||||
if (File.Exists(autoRunFile))
|
if (File.Exists(autoRunFile))
|
||||||
File.Delete(autoRunFile);
|
File.Delete(autoRunFile);
|
||||||
|
|
||||||
// TODO: Don't do anything if running a development build, only auto-run release builds
|
if (Constants.BuildInfo.IsLocalBuild)
|
||||||
|
return;
|
||||||
|
|
||||||
// Create or remove the task if necessary
|
// Create or remove the task if necessary
|
||||||
try
|
try
|
||||||
@ -314,26 +318,13 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
|||||||
bool taskCreated = false;
|
bool taskCreated = false;
|
||||||
if (!recreate)
|
if (!recreate)
|
||||||
{
|
{
|
||||||
Process schtasks = new()
|
taskCreated = SettingsUtilities.IsAutoRunTaskCreated();
|
||||||
{
|
|
||||||
StartInfo =
|
|
||||||
{
|
|
||||||
WindowStyle = ProcessWindowStyle.Hidden,
|
|
||||||
UseShellExecute = true,
|
|
||||||
FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"),
|
|
||||||
Arguments = "/TN \"Artemis 2 autorun\""
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
schtasks.Start();
|
|
||||||
schtasks.WaitForExit();
|
|
||||||
taskCreated = schtasks.ExitCode == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StartWithWindows && !taskCreated)
|
if (StartWithWindows && !taskCreated)
|
||||||
CreateAutoRunTask();
|
SettingsUtilities.CreateAutoRunTask(TimeSpan.FromSeconds(AutoRunDelay));
|
||||||
else if (!StartWithWindows && taskCreated)
|
else if (!StartWithWindows && taskCreated)
|
||||||
RemoveAutoRunTask();
|
SettingsUtilities.RemoveAutoRunTask();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -341,71 +332,10 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateAutoRunTask()
|
|
||||||
{
|
|
||||||
XDocument document = XDocument.Parse(Resources.artemis_autorun);
|
|
||||||
XElement task = document.Descendants().First();
|
|
||||||
|
|
||||||
task.Descendants().First(d => d.Name.LocalName == "RegistrationInfo").Descendants().First(d => d.Name.LocalName == "Date")
|
|
||||||
.SetValue(DateTime.Now);
|
|
||||||
task.Descendants().First(d => d.Name.LocalName == "RegistrationInfo").Descendants().First(d => d.Name.LocalName == "Author")
|
|
||||||
.SetValue(WindowsIdentity.GetCurrent().Name);
|
|
||||||
|
|
||||||
task.Descendants().First(d => d.Name.LocalName == "Triggers").Descendants().First(d => d.Name.LocalName == "LogonTrigger").Descendants().First(d => d.Name.LocalName == "Delay")
|
|
||||||
.SetValue(TimeSpan.FromSeconds(AutoRunDelay));
|
|
||||||
|
|
||||||
task.Descendants().First(d => d.Name.LocalName == "Principals").Descendants().First(d => d.Name.LocalName == "Principal").Descendants().First(d => d.Name.LocalName == "UserId")
|
|
||||||
.SetValue(WindowsIdentity.GetCurrent().User.Value);
|
|
||||||
|
|
||||||
task.Descendants().First(d => d.Name.LocalName == "Actions").Descendants().First(d => d.Name.LocalName == "Exec").Descendants().First(d => d.Name.LocalName == "WorkingDirectory")
|
|
||||||
.SetValue(Constants.ApplicationFolder);
|
|
||||||
task.Descendants().First(d => d.Name.LocalName == "Actions").Descendants().First(d => d.Name.LocalName == "Exec").Descendants().First(d => d.Name.LocalName == "Command")
|
|
||||||
.SetValue("\"" + Constants.ExecutablePath + "\"");
|
|
||||||
|
|
||||||
string xmlPath = Path.GetTempFileName();
|
|
||||||
using (Stream fileStream = new FileStream(xmlPath, FileMode.Create))
|
|
||||||
{
|
|
||||||
document.Save(fileStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
Process schtasks = new()
|
|
||||||
{
|
|
||||||
StartInfo =
|
|
||||||
{
|
|
||||||
WindowStyle = ProcessWindowStyle.Hidden,
|
|
||||||
UseShellExecute = true,
|
|
||||||
Verb = "runas",
|
|
||||||
FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"),
|
|
||||||
Arguments = $"/Create /XML \"{xmlPath}\" /tn \"Artemis 2 autorun\" /F"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
schtasks.Start();
|
|
||||||
schtasks.WaitForExit();
|
|
||||||
|
|
||||||
File.Delete(xmlPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveAutoRunTask()
|
|
||||||
{
|
|
||||||
Process schtasks = new()
|
|
||||||
{
|
|
||||||
StartInfo =
|
|
||||||
{
|
|
||||||
WindowStyle = ProcessWindowStyle.Hidden,
|
|
||||||
UseShellExecute = true,
|
|
||||||
Verb = "runas",
|
|
||||||
FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"),
|
|
||||||
Arguments = "/Delete /TN \"Artemis 2 autorun\" /f"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
schtasks.Start();
|
|
||||||
schtasks.WaitForExit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public enum ApplicationColorScheme
|
public enum ApplicationColorScheme
|
||||||
{
|
{
|
||||||
Light,
|
Light,
|
||||||
|
|||||||
@ -45,8 +45,17 @@
|
|||||||
<TextBlock Grid.Column="1" Text="{Binding FeatureInfo.Name}" Style="{StaticResource MaterialDesignTextBlock}" VerticalAlignment="Center" ToolTip="{Binding FeatureInfo.Description}" />
|
<TextBlock Grid.Column="1" Text="{Binding FeatureInfo.Name}" Style="{StaticResource MaterialDesignTextBlock}" VerticalAlignment="Center" ToolTip="{Binding FeatureInfo.Description}" />
|
||||||
|
|
||||||
<!-- Enable toggle column -->
|
<!-- Enable toggle column -->
|
||||||
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="8"
|
<StackPanel Grid.Column="2"
|
||||||
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay, FallbackValue=Collapsed}">
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="8"
|
||||||
|
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay, FallbackValue=Collapsed}"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<materialDesign:PackIcon Kind="ShieldHalfFull"
|
||||||
|
ToolTip="Plugin requires admin rights"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0 0 5 0"
|
||||||
|
Visibility="{Binding ShowShield, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
|
||||||
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding IsEnabled}" IsEnabled="{Binding FeatureInfo.Plugin.IsEnabled}">
|
<CheckBox Style="{StaticResource MaterialDesignCheckBox}" IsChecked="{Binding IsEnabled}" IsEnabled="{Binding FeatureInfo.Plugin.IsEnabled}">
|
||||||
Feature enabled
|
Feature enabled
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
|
|||||||
@ -11,26 +11,33 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
{
|
{
|
||||||
public class PluginFeatureViewModel : Screen
|
public class PluginFeatureViewModel : Screen
|
||||||
{
|
{
|
||||||
|
private readonly ICoreService _coreService;
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
private bool _enabling;
|
private bool _enabling;
|
||||||
private readonly IMessageService _messageService;
|
private readonly IMessageService _messageService;
|
||||||
|
|
||||||
public PluginFeatureViewModel(PluginFeatureInfo pluginFeatureInfo,
|
public PluginFeatureViewModel(PluginFeatureInfo pluginFeatureInfo,
|
||||||
|
bool showShield,
|
||||||
|
ICoreService coreService,
|
||||||
IDialogService dialogService,
|
IDialogService dialogService,
|
||||||
IPluginManagementService pluginManagementService,
|
IPluginManagementService pluginManagementService,
|
||||||
IMessageService messageService)
|
IMessageService messageService)
|
||||||
{
|
{
|
||||||
|
_coreService = coreService;
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_messageService = messageService;
|
_messageService = messageService;
|
||||||
|
|
||||||
FeatureInfo = pluginFeatureInfo;
|
FeatureInfo = pluginFeatureInfo;
|
||||||
|
ShowShield = FeatureInfo.Plugin.Info.RequiresAdmin && showShield;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginFeatureInfo FeatureInfo { get; }
|
public PluginFeatureInfo FeatureInfo { get; }
|
||||||
public Exception LoadException => FeatureInfo.Instance?.LoadException;
|
public Exception LoadException => FeatureInfo.Instance?.LoadException;
|
||||||
|
|
||||||
|
public bool ShowShield { get; }
|
||||||
|
|
||||||
public bool Enabling
|
public bool Enabling
|
||||||
{
|
{
|
||||||
get => _enabling;
|
get => _enabling;
|
||||||
@ -95,6 +102,16 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (FeatureInfo.Plugin.Info.RequiresAdmin && !_coreService.IsElevated)
|
||||||
|
{
|
||||||
|
bool confirmed = await _dialogService.ShowConfirmDialog("Enable feature", "The plugin of this feature requires admin rights, are you sure you want to enable it?");
|
||||||
|
if (!confirmed)
|
||||||
|
{
|
||||||
|
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await Task.Run(() => _pluginManagementService.EnablePluginFeature(FeatureInfo.Instance, true));
|
await Task.Run(() => _pluginManagementService.EnablePluginFeature(FeatureInfo.Instance, true));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@ -118,7 +118,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
protected override void OnInitialActivate()
|
protected override void OnInitialActivate()
|
||||||
{
|
{
|
||||||
foreach (PluginFeatureInfo pluginFeatureInfo in Plugin.Features)
|
foreach (PluginFeatureInfo pluginFeatureInfo in Plugin.Features)
|
||||||
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeatureInfo));
|
Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeatureInfo, false));
|
||||||
|
|
||||||
base.OnInitialActivate();
|
base.OnInitialActivate();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mde="https://spiegelp.github.io/MaterialDesignExtensions/winfx/xaml"
|
xmlns:mde="https://spiegelp.github.io/MaterialDesignExtensions/winfx/xaml"
|
||||||
xmlns:s="https://github.com/canton7/Stylet"
|
xmlns:s="https://github.com/canton7/Stylet"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Width="800"
|
Width="800"
|
||||||
Height="600"
|
Height="600"
|
||||||
@ -17,47 +18,58 @@
|
|||||||
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
|
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
|
||||||
UseLayoutRounding="True"
|
UseLayoutRounding="True"
|
||||||
d:DesignHeight="450" d:DesignWidth="800">
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
|
<materialDesign:DialogHost IsTabStop="False"
|
||||||
<mde:Stepper IsLinear="True" Layout="Horizontal" ActiveStepChanged="{s:Action ActiveStepChanged}" CancelNavigation="{s:Action SkipOrFinishWizard}" Margin="15">
|
Focusable="False"
|
||||||
<mde:Step>
|
Identifier="RootDialog"
|
||||||
<mde:Step.Header>
|
DialogTheme="Inherit"
|
||||||
<mde:StepTitleHeader FirstLevelTitle="Welcome" />
|
SnackbarMessageQueue="{Binding MainMessageQueue}">
|
||||||
</mde:Step.Header>
|
<Grid>
|
||||||
<mde:Step.Content>
|
<mde:Stepper IsLinear="True" Layout="Horizontal" ActiveStepChanged="{s:Action ActiveStepChanged}" CancelNavigation="{s:Action SkipOrFinishWizard}" Margin="15">
|
||||||
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
<mde:Step>
|
||||||
</mde:Step.Content>
|
<mde:Step.Header>
|
||||||
</mde:Step>
|
<mde:StepTitleHeader FirstLevelTitle="Welcome" />
|
||||||
<mde:Step>
|
</mde:Step.Header>
|
||||||
<mde:Step.Header>
|
<mde:Step.Content>
|
||||||
<mde:StepTitleHeader FirstLevelTitle="Devices" SecondLevelTitle="Pick your brands" />
|
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
||||||
</mde:Step.Header>
|
</mde:Step.Content>
|
||||||
<mde:Step.Content>
|
</mde:Step>
|
||||||
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
<mde:Step>
|
||||||
</mde:Step.Content>
|
<mde:Step.Header>
|
||||||
</mde:Step>
|
<mde:StepTitleHeader FirstLevelTitle="Devices" SecondLevelTitle="Pick your brands" />
|
||||||
<mde:Step>
|
</mde:Step.Header>
|
||||||
<mde:Step.Header>
|
<mde:Step.Content>
|
||||||
<mde:StepTitleHeader FirstLevelTitle="Desktop layout" SecondLevelTitle="Map your surface" />
|
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
||||||
</mde:Step.Header>
|
</mde:Step.Content>
|
||||||
<mde:Step.Content>
|
</mde:Step>
|
||||||
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
<mde:Step>
|
||||||
</mde:Step.Content>
|
<mde:Step.Header>
|
||||||
</mde:Step>
|
<mde:StepTitleHeader FirstLevelTitle="Desktop layout" SecondLevelTitle="Map your surface" />
|
||||||
<mde:Step>
|
</mde:Step.Header>
|
||||||
<mde:Step.Header>
|
<mde:Step.Content>
|
||||||
<mde:StepTitleHeader FirstLevelTitle="Settings" SecondLevelTitle="Set your preferences" />
|
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
||||||
</mde:Step.Header>
|
</mde:Step.Content>
|
||||||
<mde:Step.Content>
|
</mde:Step>
|
||||||
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
<mde:Step>
|
||||||
</mde:Step.Content>
|
<mde:Step.Header>
|
||||||
</mde:Step>
|
<mde:StepTitleHeader FirstLevelTitle="Settings" SecondLevelTitle="Set your preferences" />
|
||||||
<mde:Step>
|
</mde:Step.Header>
|
||||||
<mde:Step.Header>
|
<mde:Step.Content>
|
||||||
<mde:StepTitleHeader FirstLevelTitle="Finish" />
|
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
||||||
</mde:Step.Header>
|
</mde:Step.Content>
|
||||||
<mde:Step.Content>
|
</mde:Step>
|
||||||
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
<mde:Step>
|
||||||
</mde:Step.Content>
|
<mde:Step.Header>
|
||||||
</mde:Step>
|
<mde:StepTitleHeader FirstLevelTitle="Finish" />
|
||||||
</mde:Stepper>
|
</mde:Step.Header>
|
||||||
|
<mde:Step.Content>
|
||||||
|
<ContentControl s:View.Model="{Binding ActiveItem}" />
|
||||||
|
</mde:Step.Content>
|
||||||
|
</mde:Step>
|
||||||
|
</mde:Stepper>
|
||||||
|
<materialDesign:Snackbar x:Name="MainSnackbar"
|
||||||
|
MessageQueue="{Binding MainMessageQueue}"
|
||||||
|
materialDesign:SnackbarMessage.InlineActionButtonMaxHeight="80"
|
||||||
|
materialDesign:SnackbarMessage.ContentMaxHeight="200" />
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:DialogHost>
|
||||||
</mde:MaterialWindow>
|
</mde:MaterialWindow>
|
||||||
@ -2,18 +2,22 @@
|
|||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Screens.StartupWizard.Steps;
|
using Artemis.UI.Screens.StartupWizard.Steps;
|
||||||
|
using Artemis.UI.Shared.Services;
|
||||||
using MaterialDesignExtensions.Controllers;
|
using MaterialDesignExtensions.Controllers;
|
||||||
using MaterialDesignExtensions.Controls;
|
using MaterialDesignExtensions.Controls;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.StartupWizard
|
namespace Artemis.UI.Screens.StartupWizard
|
||||||
{
|
{
|
||||||
public class StartupWizardViewModel : Conductor<Screen>.Collection.OneActive
|
public class StartupWizardViewModel : Conductor<Screen>.Collection.OneActive
|
||||||
{
|
{
|
||||||
|
private readonly IMessageService _messageService;
|
||||||
private readonly ISettingsService _settingsService;
|
private readonly ISettingsService _settingsService;
|
||||||
private StepperController _stepperController;
|
private StepperController _stepperController;
|
||||||
|
|
||||||
public StartupWizardViewModel(ISettingsService settingsService,
|
public StartupWizardViewModel(ISettingsService settingsService,
|
||||||
|
IMessageService messageService,
|
||||||
WelcomeStepViewModel welcome,
|
WelcomeStepViewModel welcome,
|
||||||
DevicesStepViewModel devices,
|
DevicesStepViewModel devices,
|
||||||
LayoutStepViewModel layout,
|
LayoutStepViewModel layout,
|
||||||
@ -21,6 +25,7 @@ namespace Artemis.UI.Screens.StartupWizard
|
|||||||
FinishStepViewModel finish)
|
FinishStepViewModel finish)
|
||||||
{
|
{
|
||||||
_settingsService = settingsService;
|
_settingsService = settingsService;
|
||||||
|
_messageService = messageService;
|
||||||
Items.Add(welcome);
|
Items.Add(welcome);
|
||||||
Items.Add(devices);
|
Items.Add(devices);
|
||||||
Items.Add(layout);
|
Items.Add(layout);
|
||||||
@ -30,6 +35,8 @@ namespace Artemis.UI.Screens.StartupWizard
|
|||||||
ActiveItem = Items.First();
|
ActiveItem = Items.First();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ISnackbarMessageQueue MainMessageQueue { get; set; }
|
||||||
|
|
||||||
public void ActiveStepChanged(object sender, ActiveStepChangedEventArgs e)
|
public void ActiveStepChanged(object sender, ActiveStepChangedEventArgs e)
|
||||||
{
|
{
|
||||||
Stepper stepper = (Stepper) sender;
|
Stepper stepper = (Stepper) sender;
|
||||||
@ -40,22 +47,23 @@ namespace Artemis.UI.Screens.StartupWizard
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void SkipOrFinishWizard()
|
public void SkipOrFinishWizard()
|
||||||
{
|
|
||||||
RequestClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnClose()
|
|
||||||
{
|
{
|
||||||
PluginSetting<bool> setting = _settingsService.GetSetting("UI.SetupWizardCompleted", false);
|
PluginSetting<bool> setting = _settingsService.GetSetting("UI.SetupWizardCompleted", false);
|
||||||
setting.Value = true;
|
setting.Value = true;
|
||||||
setting.Save();
|
setting.Save();
|
||||||
|
|
||||||
base.OnClose();
|
RequestClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Continue()
|
public void Continue()
|
||||||
{
|
{
|
||||||
_stepperController.Continue();
|
_stepperController.Continue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnInitialActivate()
|
||||||
|
{
|
||||||
|
MainMessageQueue = _messageService.MainMessageQueue;
|
||||||
|
base.OnInitialActivate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@
|
|||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TextBlock Grid.Row="0" Style="{StaticResource MaterialDesignBody1TextBlock}" TextWrapping="Wrap">
|
<TextBlock Grid.Row="0" Style="{StaticResource MaterialDesignBody1TextBlock}" TextWrapping="Wrap">
|
||||||
EnabledDevices are supported through the use of device providers. <LineBreak />
|
Devices are supported through the use of device providers. <LineBreak />
|
||||||
In the list below you can enable device providers for each brand you own by checking <Run Text="Feature enabled" FontWeight="Bold" />.
|
In the list below you can enable device providers for each brand you own by checking <Run Text="Feature enabled" FontWeight="Bold" />.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,7 @@ namespace Artemis.UI.Screens.StartupWizard.Steps
|
|||||||
IEnumerable<PluginFeatureInfo> features = _pluginManagementService.GetAllPlugins()
|
IEnumerable<PluginFeatureInfo> features = _pluginManagementService.GetAllPlugins()
|
||||||
.SelectMany(p => p.Features.Where(f => typeof(DeviceProvider).IsAssignableFrom(f.FeatureType)))
|
.SelectMany(p => p.Features.Where(f => typeof(DeviceProvider).IsAssignableFrom(f.FeatureType)))
|
||||||
.OrderBy(d => d.GetType().Name);
|
.OrderBy(d => d.GetType().Name);
|
||||||
Items.AddRange(features.Select(d => _settingsVmFactory.CreatePluginFeatureViewModel(d)));
|
Items.AddRange(features.Select(d => _settingsVmFactory.CreatePluginFeatureViewModel(d, true)));
|
||||||
|
|
||||||
base.OnActivate();
|
base.OnActivate();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ using Artemis.UI.Screens.Settings.Tabs.General;
|
|||||||
using Artemis.UI.Screens.Settings.Tabs.Plugins;
|
using Artemis.UI.Screens.Settings.Tabs.Plugins;
|
||||||
using Artemis.UI.Shared;
|
using Artemis.UI.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Artemis.UI.Utilities;
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.StartupWizard.Steps
|
namespace Artemis.UI.Screens.StartupWizard.Steps
|
||||||
@ -34,7 +35,7 @@ namespace Artemis.UI.Screens.StartupWizard.Steps
|
|||||||
_settingsService.GetSetting("UI.AutoRun", false).Value = value;
|
_settingsService.GetSetting("UI.AutoRun", false).Value = value;
|
||||||
_settingsService.GetSetting("UI.AutoRun", false).Save();
|
_settingsService.GetSetting("UI.AutoRun", false).Save();
|
||||||
NotifyOfPropertyChange(nameof(StartWithWindows));
|
NotifyOfPropertyChange(nameof(StartWithWindows));
|
||||||
Task.Run(ApplyAutorun);
|
Task.Run(() => ApplyAutorun(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,23 +60,35 @@ namespace Artemis.UI.Screens.StartupWizard.Steps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyAutorun()
|
private void ApplyAutorun(bool recreate)
|
||||||
{
|
{
|
||||||
|
if (!StartWithWindows)
|
||||||
|
StartMinimized = false;
|
||||||
|
|
||||||
|
// Remove the old auto-run method of placing a shortcut in shell:startup
|
||||||
|
string autoRunFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), "Artemis.lnk");
|
||||||
|
if (File.Exists(autoRunFile))
|
||||||
|
File.Delete(autoRunFile);
|
||||||
|
|
||||||
|
// Local builds shouldn't auto-run, this is just annoying
|
||||||
|
// if (Constants.BuildInfo.IsLocalBuild)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// Create or remove the task if necessary
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string autoRunFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), "Artemis.lnk");
|
bool taskCreated = false;
|
||||||
string executableFile = Constants.ExecutablePath;
|
if (!recreate)
|
||||||
|
taskCreated = SettingsUtilities.IsAutoRunTaskCreated();
|
||||||
|
|
||||||
if (File.Exists(autoRunFile))
|
if (StartWithWindows && !taskCreated)
|
||||||
File.Delete(autoRunFile);
|
SettingsUtilities.CreateAutoRunTask(TimeSpan.FromSeconds(15));
|
||||||
if (StartWithWindows)
|
else if (!StartWithWindows && taskCreated)
|
||||||
ShortcutUtilities.Create(autoRunFile, executableFile, "--autorun", new FileInfo(executableFile).DirectoryName, "Artemis", "", "");
|
SettingsUtilities.RemoveAutoRunTask();
|
||||||
else
|
|
||||||
StartMinimized = false;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_dialogService.ShowExceptionDialog("An exception occured while trying to apply the auto run setting", e);
|
Execute.PostToUIThread(() => _dialogService.ShowExceptionDialog("An exception occured while trying to apply the auto run setting", e));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
95
src/Artemis.UI/Utilities/SettingsUtilities.cs
Normal file
95
src/Artemis.UI/Utilities/SettingsUtilities.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Properties;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Utilities
|
||||||
|
{
|
||||||
|
public static class SettingsUtilities
|
||||||
|
{
|
||||||
|
public static bool IsAutoRunTaskCreated()
|
||||||
|
{
|
||||||
|
Process schtasks = new()
|
||||||
|
{
|
||||||
|
StartInfo =
|
||||||
|
{
|
||||||
|
WindowStyle = ProcessWindowStyle.Hidden,
|
||||||
|
UseShellExecute = true,
|
||||||
|
FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"),
|
||||||
|
Arguments = "/TN \"Artemis 2 autorun\""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
schtasks.Start();
|
||||||
|
schtasks.WaitForExit();
|
||||||
|
return schtasks.ExitCode == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateAutoRunTask(TimeSpan autoRunDelay)
|
||||||
|
{
|
||||||
|
XDocument document = XDocument.Parse(Resources.artemis_autorun);
|
||||||
|
XElement task = document.Descendants().First();
|
||||||
|
|
||||||
|
task.Descendants().First(d => d.Name.LocalName == "RegistrationInfo").Descendants().First(d => d.Name.LocalName == "Date")
|
||||||
|
.SetValue(DateTime.Now);
|
||||||
|
task.Descendants().First(d => d.Name.LocalName == "RegistrationInfo").Descendants().First(d => d.Name.LocalName == "Author")
|
||||||
|
.SetValue(WindowsIdentity.GetCurrent().Name);
|
||||||
|
|
||||||
|
task.Descendants().First(d => d.Name.LocalName == "Triggers").Descendants().First(d => d.Name.LocalName == "LogonTrigger").Descendants().First(d => d.Name.LocalName == "Delay")
|
||||||
|
.SetValue(autoRunDelay);
|
||||||
|
|
||||||
|
task.Descendants().First(d => d.Name.LocalName == "Principals").Descendants().First(d => d.Name.LocalName == "Principal").Descendants().First(d => d.Name.LocalName == "UserId")
|
||||||
|
.SetValue(WindowsIdentity.GetCurrent().User.Value);
|
||||||
|
|
||||||
|
task.Descendants().First(d => d.Name.LocalName == "Actions").Descendants().First(d => d.Name.LocalName == "Exec").Descendants().First(d => d.Name.LocalName == "WorkingDirectory")
|
||||||
|
.SetValue(Constants.ApplicationFolder);
|
||||||
|
task.Descendants().First(d => d.Name.LocalName == "Actions").Descendants().First(d => d.Name.LocalName == "Exec").Descendants().First(d => d.Name.LocalName == "Command")
|
||||||
|
.SetValue("\"" + Constants.ExecutablePath + "\"");
|
||||||
|
|
||||||
|
string xmlPath = Path.GetTempFileName();
|
||||||
|
using (Stream fileStream = new FileStream(xmlPath, FileMode.Create))
|
||||||
|
{
|
||||||
|
document.Save(fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
Process schtasks = new()
|
||||||
|
{
|
||||||
|
StartInfo =
|
||||||
|
{
|
||||||
|
WindowStyle = ProcessWindowStyle.Hidden,
|
||||||
|
UseShellExecute = true,
|
||||||
|
Verb = "runas",
|
||||||
|
FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"),
|
||||||
|
Arguments = $"/Create /XML \"{xmlPath}\" /tn \"Artemis 2 autorun\" /F"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
schtasks.Start();
|
||||||
|
schtasks.WaitForExit();
|
||||||
|
|
||||||
|
File.Delete(xmlPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveAutoRunTask()
|
||||||
|
{
|
||||||
|
Process schtasks = new()
|
||||||
|
{
|
||||||
|
StartInfo =
|
||||||
|
{
|
||||||
|
WindowStyle = ProcessWindowStyle.Hidden,
|
||||||
|
UseShellExecute = true,
|
||||||
|
Verb = "runas",
|
||||||
|
FileName = Path.Combine(Environment.SystemDirectory, "schtasks.exe"),
|
||||||
|
Arguments = "/Delete /TN \"Artemis 2 autorun\" /f"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
schtasks.Start();
|
||||||
|
schtasks.WaitForExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user