-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into feature/flags-with-custom-images
- Loading branch information
Showing
28 changed files
with
812 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
StreamDeckSimHub.Installer/Actions/AbstractInstallerAction.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright (C) 2024 Martin Renner | ||
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER) | ||
|
||
using System.Windows.Media; | ||
using CommunityToolkit.Mvvm.ComponentModel; | ||
|
||
namespace StreamDeckSimHub.Installer.Actions; | ||
|
||
public abstract partial class AbstractInstallerAction : ObservableObject, IInstallerAction | ||
{ | ||
private readonly NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger(); | ||
|
||
public abstract string Name { get; } | ||
|
||
[ObservableProperty] | ||
private string _message = string.Empty; | ||
|
||
[ObservableProperty] | ||
private Brush _actionResultColor = ActionColors.InactiveBrush; | ||
|
||
public async Task<ActionResult> Execute() | ||
{ | ||
_logger.Info($"Starting action {GetType().Name}"); | ||
|
||
ActionResultColor = ActionColors.RunningBrush; | ||
try | ||
{ | ||
var result = await ExecuteInternal(); | ||
ActionResultColor = result switch | ||
{ | ||
ActionResult.Success => ActionColors.SuccessBrush, | ||
ActionResult.Error => ActionColors.ErrorBrush, | ||
ActionResult.NotRequired => ActionColors.InactiveBrush, | ||
ActionResult.Warning => ActionColors.WarningBrush, | ||
_ => throw new ArgumentOutOfRangeException() | ||
}; | ||
|
||
_logger.Info($"Finished action {GetType().Name} with result {result}"); | ||
|
||
// Give the user a tiny moment to realize that there is something going on. | ||
await Task.Delay(1000); | ||
|
||
return result; | ||
} | ||
catch (Exception e) | ||
{ | ||
SetAndLogError(e, $"Action {GetType().Name} failed with exception"); | ||
return ActionResult.Error; | ||
} | ||
} | ||
|
||
protected abstract Task<ActionResult> ExecuteInternal(); | ||
|
||
protected void SetAndLogInfo(string message) | ||
{ | ||
Message = message; | ||
_logger.Info(message); | ||
} | ||
|
||
protected void SetAndLogError(string message) | ||
{ | ||
Message = message; | ||
_logger.Info(message); | ||
} | ||
|
||
protected void SetAndLogError(Exception e, string message) | ||
{ | ||
Message = message; | ||
_logger.Error(e, message); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (C) 2024 Martin Renner | ||
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER) | ||
|
||
using System.Windows.Media; | ||
|
||
namespace StreamDeckSimHub.Installer.Actions; | ||
|
||
public enum ActionResult | ||
{ | ||
NotRequired, | ||
Success, | ||
Warning, | ||
Error, | ||
} | ||
|
||
public abstract class ActionColors | ||
{ | ||
public static readonly Brush InactiveBrush = Brushes.Gray; | ||
public static readonly Brush RunningBrush = Brushes.Orange; | ||
public static readonly Brush SuccessBrush = Brushes.Green; | ||
public static readonly Brush ErrorBrush = Brushes.Red; | ||
public static readonly Brush WarningBrush = Brushes.Yellow; | ||
} | ||
|
||
/// <summary> | ||
/// An action that can be executed by the installer. | ||
/// </summary> | ||
/// <remarks>Holds the action logic, but is also misused as a ViewModel.</remarks> | ||
public interface IInstallerAction | ||
{ | ||
/// <summary> | ||
/// Displayed as header in the UI. | ||
/// </summary> | ||
string Name { get; } | ||
|
||
/// <summary> | ||
/// Detailed message below the header. | ||
/// </summary> | ||
string Message { get; } | ||
|
||
/// <summary> | ||
/// Result of the action in the form of a colored brush. | ||
/// </summary> | ||
Brush ActionResultColor { get; } | ||
|
||
/// <summary> | ||
/// Executes the action. | ||
/// </summary> | ||
/// <returns>matic result of the action. Is used in the installer logic.</returns> | ||
Task<ActionResult> Execute(); | ||
} |
88 changes: 88 additions & 0 deletions
88
StreamDeckSimHub.Installer/Actions/InstallStreamDeckPlugin.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// Copyright (C) 2024 Martin Renner | ||
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER) | ||
|
||
using System.IO; | ||
using System.IO.Compression; | ||
using StreamDeckSimHub.Installer.Tools; | ||
|
||
namespace StreamDeckSimHub.Installer.Actions; | ||
|
||
public class InstallStreamDeckPlugin : AbstractInstallerAction | ||
{ | ||
public override string Name => "Installing Stream Deck SimHub Plugin"; | ||
|
||
protected override Task<ActionResult> ExecuteInternal() | ||
{ | ||
if (Directory.Exists(Path.Combine(Configuration.StreamDeckPluginDir, Configuration.PluginDirName))) | ||
{ | ||
SetAndLogInfo("Deleting existing Stream Deck SimHub Plugin"); | ||
var result = DeleteExistingInstallation(Path.Combine(Configuration.StreamDeckPluginDir, Configuration.PluginDirName)); | ||
if (!result) | ||
{ | ||
return Task.FromResult(ActionResult.Error); | ||
} | ||
} | ||
|
||
SetAndLogInfo("Installing Stream Deck SimHub Plugin"); | ||
if (!ExtractPlugin(Configuration.StreamDeckPluginDir)) | ||
{ | ||
return Task.FromResult(ActionResult.Error); | ||
} | ||
|
||
SetAndLogInfo("Successfully installed Stream Deck SimHub Plugin"); | ||
return Task.FromResult(ActionResult.Success); | ||
} | ||
|
||
private bool DeleteExistingInstallation(string pluginDir) | ||
{ | ||
try | ||
{ | ||
// Delete all files in the base directory | ||
var baseDirInfo = new DirectoryInfo(pluginDir); | ||
foreach (var fileInfo in baseDirInfo.EnumerateFiles()) | ||
{ | ||
fileInfo.Delete(); | ||
} | ||
|
||
// Delete all directories recursive in the base directory - except "images" | ||
foreach (var dirInfo in baseDirInfo.EnumerateDirectories().Where(dirInfo => dirInfo.Name != "images")) | ||
{ | ||
dirInfo.Delete(true); | ||
} | ||
|
||
// Delete all directories recursive in the "images" directory - except "custom" | ||
var imagesDirInfo = new DirectoryInfo(Path.Combine(pluginDir, "images")); | ||
foreach (var dirInfo in imagesDirInfo.EnumerateDirectories().Where(dirInfo => dirInfo.Name != "custom")) | ||
{ | ||
dirInfo.Delete(true); | ||
} | ||
|
||
return true; | ||
} | ||
catch (Exception e) | ||
{ | ||
SetAndLogError(e, $"Could not delete existing installation: {e.Message}"); | ||
return false; | ||
} | ||
} | ||
|
||
private bool ExtractPlugin(string streamDeckPluginDir) | ||
{ | ||
var myAssembly = typeof(App).Assembly; | ||
var resourcePaths = myAssembly.GetManifestResourceNames().Where(res => res.EndsWith(Configuration.PluginZipName)).ToList(); | ||
if (resourcePaths.Count == 1) | ||
{ | ||
using var pluginStream = myAssembly.GetManifestResourceStream(resourcePaths[0]); | ||
if (pluginStream == null) | ||
{ | ||
SetAndLogError("Could not find embedded Stream Deck SimHub Plugin (stream is null)"); | ||
return false; | ||
} | ||
ZipFile.ExtractToDirectory(pluginStream, streamDeckPluginDir, true); | ||
return true; | ||
} | ||
|
||
SetAndLogError($"Could not find embedded Stream Deck SimHub Plugin ({resourcePaths.Count} streams)"); | ||
return false; | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
StreamDeckSimHub.Installer/Actions/StartStreamDeckSoftware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright (C) 2024 Martin Renner | ||
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER) | ||
|
||
using System.IO; | ||
using Microsoft.Win32; | ||
using StreamDeckSimHub.Installer.Tools; | ||
|
||
namespace StreamDeckSimHub.Installer.Actions; | ||
|
||
/// <summary> | ||
/// Starts the Stream Deck software. | ||
/// </summary> | ||
public class StartStreamDeckSoftware : AbstractInstallerAction | ||
{ | ||
public override string Name => "Starting Stream Deck software"; | ||
|
||
protected override Task<ActionResult> ExecuteInternal() | ||
{ | ||
var installFolder = GetStreamDeckInstallFolder(); | ||
ProcessTools.StartProcess(Path.Combine(installFolder, "StreamDeck.exe"), installFolder); | ||
|
||
SetAndLogInfo("Stream Deck software started"); | ||
return Task.FromResult(ActionResult.Success); | ||
} | ||
|
||
private string GetStreamDeckInstallFolder() | ||
{ | ||
var installPath = (string?) Registry.GetValue(Configuration.StreamDeckRegistryFolder, Configuration.StreamDeckRegistryInstallFolder, null); | ||
if (!string.IsNullOrEmpty(installPath)) | ||
{ | ||
SetAndLogInfo($"Found Stream Deck directory in registry: {installPath}"); | ||
return installPath; | ||
} | ||
|
||
SetAndLogInfo($"Could not find Stream Deck directory in registry. Using default."); | ||
return Configuration.StreamDeckDefaultInstallFolder; | ||
} | ||
} |
Oops, something went wrong.