mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Updated shortcut repository logging
Added yet more debug logging to the software so we can get information when there is an error.
This commit is contained in:
parent
24c1ff29b4
commit
b6c007fe6f
@ -106,7 +106,6 @@
|
|||||||
<Compile Include="GlobalSuppressions.cs" />
|
<Compile Include="GlobalSuppressions.cs" />
|
||||||
<Compile Include="IconFromFile.cs" />
|
<Compile Include="IconFromFile.cs" />
|
||||||
<Compile Include="IconUtils.cs" />
|
<Compile Include="IconUtils.cs" />
|
||||||
<Compile Include="ProgressReporter.cs" />
|
|
||||||
<Compile Include="ProgramSettings.cs" />
|
<Compile Include="ProgramSettings.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
@ -118,7 +117,6 @@
|
|||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
<DependentUpon>Settings.settings</DependentUpon>
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="ShellIcon.cs" />
|
|
||||||
<Compile Include="ShortcutItem.cs" />
|
<Compile Include="ShortcutItem.cs" />
|
||||||
<Compile Include="ShortcutRepository.cs" />
|
<Compile Include="ShortcutRepository.cs" />
|
||||||
<Compile Include="UIForms\ApplyingProfileForm.cs">
|
<Compile Include="UIForms\ApplyingProfileForm.cs">
|
||||||
|
@ -1,160 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace DisplayMagician
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A class used by Tasks to report progress or completion updates back to the UI.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class ProgressReporter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The underlying scheduler for the UI's synchronization context.
|
|
||||||
/// </summary>
|
|
||||||
private readonly TaskScheduler scheduler;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ProgressReporter"/> class.
|
|
||||||
/// This should be run on a UI thread.
|
|
||||||
/// </summary>
|
|
||||||
public ProgressReporter()
|
|
||||||
{
|
|
||||||
this.scheduler = TaskScheduler.FromCurrentSynchronizationContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the task scheduler which executes tasks on the UI thread.
|
|
||||||
/// </summary>
|
|
||||||
public TaskScheduler Scheduler
|
|
||||||
{
|
|
||||||
get { return this.scheduler; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reports the progress to the UI thread. This method should be called from the task.
|
|
||||||
/// Note that the progress update is asynchronous with respect to the reporting Task.
|
|
||||||
/// For a synchronous progress update, wait on the returned <see cref="Task"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to perform in the context of the UI thread.
|
|
||||||
/// Note that this action is run asynchronously on the UI thread.</param>
|
|
||||||
/// <returns>The task queued to the UI thread.</returns>
|
|
||||||
public Task ReportProgressAsync(Action action)
|
|
||||||
{
|
|
||||||
return Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, this.scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reports the progress to the UI thread, and waits for the UI thread to process
|
|
||||||
/// the update before returning. This method should be called from the task.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="action">The action to perform in the context of the UI thread.</param>
|
|
||||||
public void ReportProgress(Action action)
|
|
||||||
{
|
|
||||||
this.ReportProgressAsync(action).Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a UI thread handler for when the specified task finishes execution,
|
|
||||||
/// whether it finishes with success, failiure, or cancellation.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="task">The task to monitor for completion.</param>
|
|
||||||
/// <param name="action">The action to take when the task has completed, in the context of the UI thread.</param>
|
|
||||||
/// <returns>The continuation created to handle completion. This is normally ignored.</returns>
|
|
||||||
public Task RegisterContinuation(Task task, Action action)
|
|
||||||
{
|
|
||||||
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.None, this.scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a UI thread handler for when the specified task finishes execution,
|
|
||||||
/// whether it finishes with success, failiure, or cancellation.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResult">The type of the task result.</typeparam>
|
|
||||||
/// <param name="task">The task to monitor for completion.</param>
|
|
||||||
/// <param name="action">The action to take when the task has completed, in the context of the UI thread.</param>
|
|
||||||
/// <returns>The continuation created to handle completion. This is normally ignored.</returns>
|
|
||||||
public Task RegisterContinuation<TResult>(Task<TResult> task, Action action)
|
|
||||||
{
|
|
||||||
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.None, this.scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a UI thread handler for when the specified task successfully finishes execution.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="task">The task to monitor for successful completion.</param>
|
|
||||||
/// <param name="action">The action to take when the task has successfully completed, in the context of the UI thread.</param>
|
|
||||||
/// <returns>The continuation created to handle successful completion. This is normally ignored.</returns>
|
|
||||||
public Task RegisterSucceededHandler(Task task, Action action)
|
|
||||||
{
|
|
||||||
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, this.scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a UI thread handler for when the specified task successfully finishes execution
|
|
||||||
/// and returns a result.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResult">The type of the task result.</typeparam>
|
|
||||||
/// <param name="task">The task to monitor for successful completion.</param>
|
|
||||||
/// <param name="action">The action to take when the task has successfully completed, in the context of the UI thread.
|
|
||||||
/// The argument to the action is the return value of the task.</param>
|
|
||||||
/// <returns>The continuation created to handle successful completion. This is normally ignored.</returns>
|
|
||||||
public Task RegisterSucceededHandler<TResult>(Task<TResult> task, Action<TResult> action)
|
|
||||||
{
|
|
||||||
return task.ContinueWith(t => action(t.Result), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, this.Scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a UI thread handler for when the specified task becomes faulted.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="task">The task to monitor for faulting.</param>
|
|
||||||
/// <param name="action">The action to take when the task has faulted, in the context of the UI thread.</param>
|
|
||||||
/// <returns>The continuation created to handle faulting. This is normally ignored.</returns>
|
|
||||||
public Task RegisterFaultedHandler(Task task, Action<Exception> action)
|
|
||||||
{
|
|
||||||
return task.ContinueWith(t => action(t.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, this.Scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a UI thread handler for when the specified task becomes faulted.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResult">The type of the task result.</typeparam>
|
|
||||||
/// <param name="task">The task to monitor for faulting.</param>
|
|
||||||
/// <param name="action">The action to take when the task has faulted, in the context of the UI thread.</param>
|
|
||||||
/// <returns>The continuation created to handle faulting. This is normally ignored.</returns>
|
|
||||||
public Task RegisterFaultedHandler<TResult>(Task<TResult> task, Action<Exception> action)
|
|
||||||
{
|
|
||||||
return task.ContinueWith(t => action(t.Exception), CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, this.Scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a UI thread handler for when the specified task is cancelled.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="task">The task to monitor for cancellation.</param>
|
|
||||||
/// <param name="action">The action to take when the task is cancelled, in the context of the UI thread.</param>
|
|
||||||
/// <returns>The continuation created to handle cancellation. This is normally ignored.</returns>
|
|
||||||
public Task RegisterCancelledHandler(Task task, Action action)
|
|
||||||
{
|
|
||||||
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a UI thread handler for when the specified task is cancelled.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TResult">The type of the task result.</typeparam>
|
|
||||||
/// <param name="task">The task to monitor for cancellation.</param>
|
|
||||||
/// <param name="action">The action to take when the task is cancelled, in the context of the UI thread.</param>
|
|
||||||
/// <returns>The continuation created to handle cancellation. This is normally ignored.</returns>
|
|
||||||
public Task RegisterCancelledHandler<TResult>(Task<TResult> task, Action action)
|
|
||||||
{
|
|
||||||
return task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------
|
|
||||||
// <copyright file="ShellIcon.cs" company="Mauricio DIAZ ORLICH (madd0@madd0.com)">
|
|
||||||
// Distributed under Microsoft Public License (MS-PL).
|
|
||||||
// http://www.opensource.org/licenses/MS-PL
|
|
||||||
// </copyright>
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace DisplayMagician {
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a small or large Icon with an easy C# function call
|
|
||||||
/// that returns a 32x32 or 16x16 System.Drawing.Icon depending on which function you call
|
|
||||||
/// either GetSmallIcon(string fileName) or GetLargeIcon(string fileName)
|
|
||||||
/// </summary>
|
|
||||||
public static class ShellIcon
|
|
||||||
{
|
|
||||||
#region Interop constants
|
|
||||||
|
|
||||||
private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
|
|
||||||
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x10;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Interop data types
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
private struct SHFILEINFO
|
|
||||||
{
|
|
||||||
public IntPtr hIcon;
|
|
||||||
public IntPtr iIcon;
|
|
||||||
public uint dwAttributes;
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
|
||||||
public string szDisplayName;
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
|
|
||||||
public string szTypeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
private enum SHGFI : int
|
|
||||||
{
|
|
||||||
/// <summary>get icon</summary>
|
|
||||||
Icon = 0x000000100,
|
|
||||||
/// <summary>get display name</summary>
|
|
||||||
DisplayName = 0x000000200,
|
|
||||||
/// <summary>get type name</summary>
|
|
||||||
TypeName = 0x000000400,
|
|
||||||
/// <summary>get attributes</summary>
|
|
||||||
Attributes = 0x000000800,
|
|
||||||
/// <summary>get icon location</summary>
|
|
||||||
IconLocation = 0x000001000,
|
|
||||||
/// <summary>return exe type</summary>
|
|
||||||
ExeType = 0x000002000,
|
|
||||||
/// <summary>get system icon index</summary>
|
|
||||||
SysIconIndex = 0x000004000,
|
|
||||||
/// <summary>put a link overlay on icon</summary>
|
|
||||||
LinkOverlay = 0x000008000,
|
|
||||||
/// <summary>show icon in selected state</summary>
|
|
||||||
Selected = 0x000010000,
|
|
||||||
/// <summary>get only specified attributes</summary>
|
|
||||||
Attr_Specified = 0x000020000,
|
|
||||||
/// <summary>get large icon</summary>
|
|
||||||
LargeIcon = 0x000000000,
|
|
||||||
/// <summary>get small icon</summary>
|
|
||||||
SmallIcon = 0x000000001,
|
|
||||||
/// <summary>get open icon</summary>
|
|
||||||
OpenIcon = 0x000000002,
|
|
||||||
/// <summary>get shell size icon</summary>
|
|
||||||
ShellIconSize = 0x000000004,
|
|
||||||
/// <summary>pszPath is a pidl</summary>
|
|
||||||
PIDL = 0x000000008,
|
|
||||||
/// <summary>use passed dwFileAttribute</summary>
|
|
||||||
UseFileAttributes = 0x000000010,
|
|
||||||
/// <summary>apply the appropriate overlays</summary>
|
|
||||||
AddOverlays = 0x000000020,
|
|
||||||
/// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
|
|
||||||
OverlayIndex = 0x000000040,
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private class Win32
|
|
||||||
{
|
|
||||||
[DllImport("shell32.dll")]
|
|
||||||
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
|
|
||||||
|
|
||||||
[DllImport("User32.dll")]
|
|
||||||
public static extern int DestroyIcon(IntPtr hIcon);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Icon GetSmallFolderIcon()
|
|
||||||
{
|
|
||||||
return GetIcon("folder", SHGFI.SmallIcon | SHGFI.UseFileAttributes, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Icon GetLargeFolderIcon()
|
|
||||||
{
|
|
||||||
return GetIcon("folder", SHGFI.LargeIcon | SHGFI.UseFileAttributes, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Icon GetSmallIcon(string fileName)
|
|
||||||
{
|
|
||||||
return GetIcon(fileName, SHGFI.SmallIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Icon GetLargeIcon(string fileName)
|
|
||||||
{
|
|
||||||
return GetIcon(fileName, SHGFI.LargeIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Icon GetSmallIconFromExtension(string extension)
|
|
||||||
{
|
|
||||||
return GetIcon(extension, SHGFI.SmallIcon | SHGFI.UseFileAttributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Icon GetLargeIconFromExtension(string extension)
|
|
||||||
{
|
|
||||||
return GetIcon(extension, SHGFI.LargeIcon | SHGFI.UseFileAttributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Icon GetIcon(string fileName, SHGFI flags, bool isFolder = false)
|
|
||||||
{
|
|
||||||
SHFILEINFO shinfo = new SHFILEINFO();
|
|
||||||
|
|
||||||
IntPtr hImgSmall = Win32.SHGetFileInfo(fileName, isFolder ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL, ref shinfo, (uint)Marshal.SizeOf(shinfo), (uint)(SHGFI.Icon | flags));
|
|
||||||
|
|
||||||
Icon icon = (Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone();
|
|
||||||
Win32.DestroyIcon(shinfo.hIcon);
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -50,14 +50,27 @@ namespace DisplayMagician
|
|||||||
Directory.CreateDirectory(AppShortcutStoragePath);
|
Directory.CreateDirectory(AppShortcutStoragePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (UnauthorizedAccessException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/ShortcutRepository: DisplayMagician doesn't have permissions to create the Shortcut storage folder {AppShortcutStoragePath}.");
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/ShortcutRepository: DisplayMagician can't create the Shortcut storage folder {AppShortcutStoragePath} due to an invalid argument.");
|
||||||
|
}
|
||||||
|
catch (PathTooLongException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/ShortcutRepository: DisplayMagician can't create the Shortcut storage folder {AppShortcutStoragePath} as the path is too long.");
|
||||||
|
}
|
||||||
|
catch (DirectoryNotFoundException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/ShortcutRepository: DisplayMagician can't create the Shortcut storage folder {AppShortcutStoragePath} as the parent folder isn't there.");
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
//Console.WriteLine($"ShortcutItem/Instansiation exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
logger.Warn(ex, $"ShortcutRepository/ShortcutRepository: Initialising NVIDIA NvAPIWrapper or CoreAudioController caused an exception.");
|
||||||
logger.Error(ex, $"ShortcutRepository/Instansiation exception during class construction");
|
|
||||||
// ignored
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Load the Shortcuts from storage
|
// Load the Shortcuts from storage
|
||||||
LoadShortcuts();
|
LoadShortcuts();
|
||||||
}
|
}
|
||||||
@ -110,6 +123,8 @@ namespace DisplayMagician
|
|||||||
#region Class Methods
|
#region Class Methods
|
||||||
public static bool AddShortcut(ShortcutItem shortcut)
|
public static bool AddShortcut(ShortcutItem shortcut)
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/AddShortcut: Adding shortcut {shortcut.Name} to our shortcut repository");
|
||||||
|
|
||||||
if (!(shortcut is ShortcutItem))
|
if (!(shortcut is ShortcutItem))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -119,9 +134,6 @@ namespace DisplayMagician
|
|||||||
//Doublecheck it's been added
|
//Doublecheck it's been added
|
||||||
if (ContainsShortcut(shortcut))
|
if (ContainsShortcut(shortcut))
|
||||||
{
|
{
|
||||||
// Generate the Shortcut Icon ready to be used
|
|
||||||
//shortcut.SaveShortcutIconToCache();
|
|
||||||
|
|
||||||
// Save the shortcuts JSON as it's different
|
// Save the shortcuts JSON as it's different
|
||||||
SaveShortcuts();
|
SaveShortcuts();
|
||||||
|
|
||||||
@ -134,6 +146,8 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
public static bool RemoveShortcut(ShortcutItem shortcut)
|
public static bool RemoveShortcut(ShortcutItem shortcut)
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RemoveShortcut: Removing shortcut {shortcut.Name} if it exists in our shortcut repository");
|
||||||
|
|
||||||
if (!(shortcut is ShortcutItem))
|
if (!(shortcut is ShortcutItem))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -143,13 +157,12 @@ namespace DisplayMagician
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
logger.Info($"ShortcutRepository/RemoveShortcut: Removing shortcut {shortcutToRemove.Name}");
|
||||||
File.Delete(shortcutToRemove.SavedShortcutIconCacheFilename);
|
File.Delete(shortcutToRemove.SavedShortcutIconCacheFilename);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ShortcutRepository/RemoveShortcut exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
logger.Error(ex, $"ShortcutRepository/RemoveShortcut: Exception removing shortcut {shortcutToRemove.Name}");
|
||||||
|
|
||||||
// TODO check and report
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,13 +183,17 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
public static bool RemoveShortcut(string shortcutNameOrUuid)
|
public static bool RemoveShortcut(string shortcutNameOrUuid)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrWhiteSpace(shortcutNameOrUuid))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
logger.Debug($"ShortcutRepository/RemoveShortcut2: Removing shortcut {shortcutNameOrUuid} if it exists in our shortcut repository");
|
||||||
|
|
||||||
|
if (String.IsNullOrWhiteSpace(shortcutNameOrUuid))
|
||||||
|
{
|
||||||
|
logger.Error($"ShortcutRepository/RemoveShortcut2: Shortcut to look for was empty or only whitespace");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
List<ShortcutItem> shortcutsToRemove;
|
List<ShortcutItem> shortcutsToRemove;
|
||||||
int numRemoved;
|
int numRemoved;
|
||||||
|
|
||||||
//string uuidV4Regex = @"/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i";
|
|
||||||
Match match = Regex.Match(shortcutNameOrUuid, uuidV4Regex, RegexOptions.IgnoreCase);
|
Match match = Regex.Match(shortcutNameOrUuid, uuidV4Regex, RegexOptions.IgnoreCase);
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
@ -193,13 +210,12 @@ namespace DisplayMagician
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
logger.Info($"ShortcutRepository/RemoveShortcut2: Removing shortcut {shortcutToRemove.Name}");
|
||||||
File.Delete(shortcutToRemove.SavedShortcutIconCacheFilename);
|
File.Delete(shortcutToRemove.SavedShortcutIconCacheFilename);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ShortcutRepository/RemoveShortcut exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
logger.Error(ex, $"ShortcutRepository/RemoveShortcut2: Exception removing shortcut {shortcutToRemove.Name}");
|
||||||
|
|
||||||
// TODO check and report
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,13 +234,19 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
public static bool ContainsShortcut(ShortcutItem shortcut)
|
public static bool ContainsShortcut(ShortcutItem shortcut)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
logger.Debug($"ShortcutRepository/ContainsShortcut: Checking whether {shortcut.Name} exists in our shortcut repository");
|
||||||
|
|
||||||
if (!(shortcut is ShortcutItem))
|
if (!(shortcut is ShortcutItem))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (ShortcutItem testShortcut in _allShortcuts)
|
foreach (ShortcutItem testShortcut in _allShortcuts)
|
||||||
{
|
{
|
||||||
if (testShortcut.UUID.Equals(shortcut.UUID,StringComparison.OrdinalIgnoreCase))
|
if (testShortcut.UUID.Equals(shortcut.UUID, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/ContainsShortcut: {shortcut.Name} does exist in our shortcut repository");
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -232,18 +254,25 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
public static bool ContainsShortcut(string shortcutNameOrUuid)
|
public static bool ContainsShortcut(string shortcutNameOrUuid)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
logger.Debug($"ShortcutRepository/ContainsShortcut2: Checking whether {shortcutNameOrUuid} exists in our shortcut repository");
|
||||||
|
|
||||||
if (String.IsNullOrWhiteSpace(shortcutNameOrUuid))
|
if (String.IsNullOrWhiteSpace(shortcutNameOrUuid))
|
||||||
|
{
|
||||||
|
logger.Error($"ShortcutRepository/ContainsShortcut2: Shortcut to look for was empty or only whitespace");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//string uuidV4Regex = @"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$";
|
|
||||||
Match match = Regex.Match(shortcutNameOrUuid, uuidV4Regex, RegexOptions.IgnoreCase);
|
Match match = Regex.Match(shortcutNameOrUuid, uuidV4Regex, RegexOptions.IgnoreCase);
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
foreach (ShortcutItem testShortcut in _allShortcuts)
|
foreach (ShortcutItem testShortcut in _allShortcuts)
|
||||||
{
|
{
|
||||||
if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
|
if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/ContainsShortcut2: Shortcut with UUID {shortcutNameOrUuid} does exist in our shortcut repository");
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -252,7 +281,10 @@ namespace DisplayMagician
|
|||||||
foreach (ShortcutItem testShortcut in _allShortcuts)
|
foreach (ShortcutItem testShortcut in _allShortcuts)
|
||||||
{
|
{
|
||||||
if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
|
if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/ContainsShortcut2: Shortcut with name {shortcutNameOrUuid} does exist in our shortcut repository");
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -264,17 +296,24 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
public static ShortcutItem GetShortcut(string shortcutNameOrUuid)
|
public static ShortcutItem GetShortcut(string shortcutNameOrUuid)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrWhiteSpace(shortcutNameOrUuid))
|
logger.Debug($"ShortcutRepository/GetShortcut: Finding and returning {shortcutNameOrUuid} if it exists in our shortcut repository");
|
||||||
return null;
|
|
||||||
|
if (String.IsNullOrWhiteSpace(shortcutNameOrUuid))
|
||||||
|
{
|
||||||
|
logger.Error($"ShortcutRepository/GetShortcut: Shortcut to get was empty or only whitespace");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
//string uuidV4Regex = @"/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i";
|
|
||||||
Match match = Regex.Match(shortcutNameOrUuid, uuidV4Regex, RegexOptions.IgnoreCase);
|
Match match = Regex.Match(shortcutNameOrUuid, uuidV4Regex, RegexOptions.IgnoreCase);
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
foreach (ShortcutItem testShortcut in _allShortcuts)
|
foreach (ShortcutItem testShortcut in _allShortcuts)
|
||||||
{
|
{
|
||||||
if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
|
if (testShortcut.UUID.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/GetShortcut: Returning shortcut with UUID {shortcutNameOrUuid}");
|
||||||
return testShortcut;
|
return testShortcut;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -283,7 +322,10 @@ namespace DisplayMagician
|
|||||||
foreach (ShortcutItem testShortcut in _allShortcuts)
|
foreach (ShortcutItem testShortcut in _allShortcuts)
|
||||||
{
|
{
|
||||||
if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
|
if (testShortcut.Name.Equals(shortcutNameOrUuid, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/GetShortcut: Returning shortcut with Name {shortcutNameOrUuid}");
|
||||||
return testShortcut;
|
return testShortcut;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -296,6 +338,8 @@ namespace DisplayMagician
|
|||||||
public static bool RenameShortcutProfile(ProfileItem newProfile)
|
public static bool RenameShortcutProfile(ProfileItem newProfile)
|
||||||
#pragma warning restore CS3001 // Argument type is not CLS-compliant
|
#pragma warning restore CS3001 // Argument type is not CLS-compliant
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RenameShortcutProfile: Renaming the profile in any shortcuts containing the old profile name");
|
||||||
|
|
||||||
if (!(newProfile is ProfileItem))
|
if (!(newProfile is ProfileItem))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -303,6 +347,7 @@ namespace DisplayMagician
|
|||||||
{
|
{
|
||||||
if (testShortcut.ProfileUUID.Equals(newProfile.UUID, StringComparison.OrdinalIgnoreCase) && testShortcut.AutoName)
|
if (testShortcut.ProfileUUID.Equals(newProfile.UUID, StringComparison.OrdinalIgnoreCase) && testShortcut.AutoName)
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RenameShortcutProfile: Renaming {testShortcut.Name} shortcut's profile to {newProfile.Name} since the original profile has just been renamed.");
|
||||||
testShortcut.ProfileToUse = newProfile;
|
testShortcut.ProfileToUse = newProfile;
|
||||||
testShortcut.AutoSuggestShortcutName();
|
testShortcut.AutoSuggestShortcutName();
|
||||||
}
|
}
|
||||||
@ -316,6 +361,8 @@ namespace DisplayMagician
|
|||||||
private static bool LoadShortcuts()
|
private static bool LoadShortcuts()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
logger.Debug($"ShortcutRepository/LoadShortcut: Loading shortcuts from {_shortcutStorageJsonFileName} into the Shortcut Repository");
|
||||||
|
|
||||||
if (File.Exists(_shortcutStorageJsonFileName))
|
if (File.Exists(_shortcutStorageJsonFileName))
|
||||||
{
|
{
|
||||||
var json = File.ReadAllText(_shortcutStorageJsonFileName, Encoding.Unicode);
|
var json = File.ReadAllText(_shortcutStorageJsonFileName, Encoding.Unicode);
|
||||||
@ -337,11 +384,14 @@ namespace DisplayMagician
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// ignored
|
logger.Error(ex, $"ShortcutRepository/LoadShortcut: Tried to parse the JSON in the {_shortcutStorageJsonFileName} but the JsonConvert threw an exception.");
|
||||||
Console.WriteLine($"Unable to load Shortcuts from JSON file {_shortcutStorageJsonFileName}: " + ex.Message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup all the Profile Names in the Saved Profiles
|
// Lookup all the Profile Names in the Saved Profiles
|
||||||
|
// and link the profiles to the Shortcuts as we only
|
||||||
|
// store the profile names to allow users to uodate profiles
|
||||||
|
// separately from the shortcuts
|
||||||
|
logger.Debug($"ShortcutRepository/LoadShortcut: Connecting Shortcut profile names to the real profile objects");
|
||||||
foreach (ShortcutItem updatedShortcut in _allShortcuts)
|
foreach (ShortcutItem updatedShortcut in _allShortcuts)
|
||||||
{
|
{
|
||||||
foreach (ProfileItem profile in ProfileRepository.AllProfiles)
|
foreach (ProfileItem profile in ProfileRepository.AllProfiles)
|
||||||
@ -355,11 +405,24 @@ namespace DisplayMagician
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We should only get here if there isn't a profile to match to.
|
||||||
|
logger.Debug($"ShortcutRepository/LoadShortcut: Couldn't find the profile with UUID {updatedShortcut.ProfileUUID} so couldn't link it to a profile! We can't use this shortcut.");
|
||||||
|
updatedShortcut.ProfileToUse = null;
|
||||||
|
updatedShortcut.IsPossible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the shortcuts alphabetically
|
// Sort the shortcuts alphabetically
|
||||||
_allShortcuts.Sort();
|
_allShortcuts.Sort();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/LoadShortcut: The {_shortcutStorageJsonFileName} shortcut JSON file exists but is empty! So we're going to treat it as if it didn't exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/LoadShortcut: Couldn't find the {_shortcutStorageJsonFileName} shortcut JSON file that contains the Shortcuts");
|
||||||
}
|
}
|
||||||
_shortcutsLoaded = true;
|
_shortcutsLoaded = true;
|
||||||
return true;
|
return true;
|
||||||
@ -367,25 +430,30 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
public static bool SaveShortcuts()
|
public static bool SaveShortcuts()
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/SaveShortcuts: Attempting to save the shortcut repository to the {_shortcutStorageJsonFileName}.");
|
||||||
|
|
||||||
if (!Directory.Exists(AppShortcutStoragePath))
|
if (!Directory.Exists(AppShortcutStoragePath))
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/SaveShortcuts: Creating the shortcut folder {AppShortcutStoragePath} as it doesn't currently exist.");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(AppShortcutStoragePath);
|
Directory.CreateDirectory(AppShortcutStoragePath);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ShortcutRepository/SaveShortcuts exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
logger.Error(ex, $"ShortcutRepository/SaveShortcuts: Unable to create Shortcut folder {AppShortcutStoragePath}.");
|
||||||
|
|
||||||
Console.WriteLine($"Unable to create Shortcut folder {AppShortcutStoragePath}: " + ex.Message);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/SaveShortcuts: Shortcut folder {AppShortcutStoragePath} exists.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/SaveShortcuts: Creating the shortcut folder {AppShortcutStoragePath} as it doesn't currently exist.");
|
||||||
|
|
||||||
var json = JsonConvert.SerializeObject(_allShortcuts, Formatting.Indented, new JsonSerializerSettings
|
var json = JsonConvert.SerializeObject(_allShortcuts, Formatting.Indented, new JsonSerializerSettings
|
||||||
{
|
{
|
||||||
NullValueHandling = NullValueHandling.Include,
|
NullValueHandling = NullValueHandling.Include,
|
||||||
@ -397,15 +465,15 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(json))
|
if (!string.IsNullOrWhiteSpace(json))
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/SaveShortcuts: Saving the shortcut repository to the {_shortcutStorageJsonFileName}.");
|
||||||
|
|
||||||
File.WriteAllText(_shortcutStorageJsonFileName, json, Encoding.Unicode);
|
File.WriteAllText(_shortcutStorageJsonFileName, json, Encoding.Unicode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ShortcutRepository/SaveShortcuts exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
|
logger.Error(ex, $"ShortcutRepository/SaveShortcuts: Unable to save the shortcut repository to the {_shortcutStorageJsonFileName}.");
|
||||||
|
|
||||||
Console.WriteLine($"Unable to save Shortcut JSON file {_shortcutStorageJsonFileName}: " + ex.Message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -414,6 +482,8 @@ namespace DisplayMagician
|
|||||||
// ReSharper disable once CyclomaticComplexity
|
// ReSharper disable once CyclomaticComplexity
|
||||||
public static void RunShortcut(ShortcutItem shortcutToUse, NotifyIcon notifyIcon = null)
|
public static void RunShortcut(ShortcutItem shortcutToUse, NotifyIcon notifyIcon = null)
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: Running the shortcut {shortcutToUse.Name}.");
|
||||||
|
|
||||||
// Do some validation to make sure the shortcut is sensible
|
// Do some validation to make sure the shortcut is sensible
|
||||||
// And that we have enough to try and action within the shortcut
|
// And that we have enough to try and action within the shortcut
|
||||||
// including checking the Profile in the shortcut is possible
|
// including checking the Profile in the shortcut is possible
|
||||||
@ -424,25 +494,27 @@ namespace DisplayMagician
|
|||||||
(bool valid, string reason) = shortcutToUse.IsValid();
|
(bool valid, string reason) = shortcutToUse.IsValid();
|
||||||
if (!valid)
|
if (!valid)
|
||||||
{
|
{
|
||||||
logger.Error($"ShortcutRepository/RunShortcut error. shortcutToUse isn't valid");
|
logger.Error($"ShortcutRepository/RunShortcut: Cannot run the shortcut {shortcutToUse.Name} as it isn't valid");
|
||||||
MessageBox.Show(
|
MessageBox.Show(
|
||||||
$"Unable to run the shortcut '{shortcutToUse.Name}': {reason}",
|
$"Unable to run the shortcut '{shortcutToUse.Name}': {reason}",
|
||||||
@"Cannot run the Shortcut",
|
@"Cannot run the Shortcut",
|
||||||
MessageBoxButtons.OK,
|
MessageBoxButtons.OK,
|
||||||
MessageBoxIcon.Exclamation);
|
MessageBoxIcon.Exclamation);
|
||||||
return;
|
return;
|
||||||
//throw new Exception(string.Format("ShortcutRepository/SaveShortcutIconToCache exception: Unable to run the shortcut '{0}': {1}", shortcutToUse.Name, reason));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember the profile we are on now
|
// Remember the profile we are on now
|
||||||
bool needToChangeProfiles = false;
|
bool needToChangeProfiles = false;
|
||||||
ProfileItem rollbackProfile = ProfileRepository.CurrentProfile;
|
ProfileItem rollbackProfile = ProfileRepository.CurrentProfile;
|
||||||
if (!rollbackProfile.Equals(shortcutToUse.ProfileToUse))
|
if (!rollbackProfile.Equals(shortcutToUse.ProfileToUse))
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: We need to change to the {shortcutToUse.ProfileToUse} profile.");
|
||||||
needToChangeProfiles = true;
|
needToChangeProfiles = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: We're already on the {rollbackProfile.Name} profile so no need to change profiles.");
|
||||||
|
}
|
||||||
// Tell the IPC Service we are busy right now, and keep the previous status for later
|
// Tell the IPC Service we are busy right now, and keep the previous status for later
|
||||||
InstanceStatus rollbackInstanceStatus = IPCService.GetInstance().Status;
|
InstanceStatus rollbackInstanceStatus = IPCService.GetInstance().Status;
|
||||||
IPCService.GetInstance().Status = InstanceStatus.Busy;
|
IPCService.GetInstance().Status = InstanceStatus.Busy;
|
||||||
@ -450,12 +522,12 @@ namespace DisplayMagician
|
|||||||
// Only change profiles if we have to
|
// Only change profiles if we have to
|
||||||
if (needToChangeProfiles)
|
if (needToChangeProfiles)
|
||||||
{
|
{
|
||||||
|
logger.Info($"ShortcutRepository/RunShortcut: Changing to the {rollbackProfile.Name} profile.");
|
||||||
// Apply the Profile!
|
// Apply the Profile!
|
||||||
Console.WriteLine($"Changing to '{shortcutToUse.ProfileToUse.Name}' Display Profile");
|
|
||||||
if (!Program.ApplyProfile(shortcutToUse.ProfileToUse))
|
if (!Program.ApplyProfile(shortcutToUse.ProfileToUse))
|
||||||
{
|
{
|
||||||
Console.WriteLine($"ERROR - Cannot apply '{shortcutToUse.ProfileToUse.Name}' Display Profile");
|
Console.WriteLine($"ERROR - Cannot apply '{shortcutToUse.ProfileToUse.Name}' Display Profile");
|
||||||
logger.Error($"ShortcutRepository/RunShortcut cannot apply '{shortcutToUse.ProfileToUse.Name}' Display Profile");
|
logger.Error($"ShortcutRepository/RunShortcut: Cannot apply '{shortcutToUse.ProfileToUse.Name}' Display Profile");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,12 +536,20 @@ namespace DisplayMagician
|
|||||||
CoreAudioDevice rollbackAudioDevice = _audioController.DefaultPlaybackDevice;
|
CoreAudioDevice rollbackAudioDevice = _audioController.DefaultPlaybackDevice;
|
||||||
double rollbackAudioVolume = _audioController.DefaultPlaybackDevice.Volume;
|
double rollbackAudioVolume = _audioController.DefaultPlaybackDevice.Volume;
|
||||||
if (!rollbackAudioDevice.FullName.Equals(shortcutToUse.AudioDevice))
|
if (!rollbackAudioDevice.FullName.Equals(shortcutToUse.AudioDevice))
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: We need to change to the {shortcutToUse.AudioDevice} audio device.");
|
||||||
needToChangeAudio = true;
|
needToChangeAudio = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: We're already using the {shortcutToUse.AudioDevice} audio device so no need to change audio devices.");
|
||||||
|
}
|
||||||
|
|
||||||
// Change Audio Device (if one specified)
|
// Change Audio Device (if one specified)
|
||||||
if (shortcutToUse.ChangeAudioDevice)
|
if (shortcutToUse.ChangeAudioDevice)
|
||||||
{
|
{
|
||||||
|
logger.Info($"ShortcutRepository/RunShortcut: Changing to the {shortcutToUse.AudioDevice} audio device.");
|
||||||
|
|
||||||
IEnumerable<CoreAudioDevice> audioDevices = _audioController.GetPlaybackDevices();
|
IEnumerable<CoreAudioDevice> audioDevices = _audioController.GetPlaybackDevices();
|
||||||
foreach (CoreAudioDevice audioDevice in audioDevices)
|
foreach (CoreAudioDevice audioDevice in audioDevices)
|
||||||
{
|
{
|
||||||
@ -480,6 +560,7 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
if (shortcutToUse.SetAudioVolume)
|
if (shortcutToUse.SetAudioVolume)
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: Setting {shortcutToUse.AudioDevice} audio level to {shortcutToUse.AudioVolume}%.");
|
||||||
Task myTask = new Task(() =>
|
Task myTask = new Task(() =>
|
||||||
{
|
{
|
||||||
audioDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.AudioVolume));
|
audioDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.AudioVolume));
|
||||||
@ -497,11 +578,19 @@ namespace DisplayMagician
|
|||||||
CoreAudioDevice rollbackCaptureDevice = _audioController.DefaultCaptureDevice;
|
CoreAudioDevice rollbackCaptureDevice = _audioController.DefaultCaptureDevice;
|
||||||
double rollbackCaptureVolume = _audioController.DefaultCaptureDevice.Volume;
|
double rollbackCaptureVolume = _audioController.DefaultCaptureDevice.Volume;
|
||||||
if (!rollbackCaptureDevice.FullName.Equals(shortcutToUse.CaptureDevice))
|
if (!rollbackCaptureDevice.FullName.Equals(shortcutToUse.CaptureDevice))
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: We need to change to the {shortcutToUse.CaptureDevice} capture (microphone) device.");
|
||||||
needToChangeCaptureDevice = true;
|
needToChangeCaptureDevice = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: We're already using the {shortcutToUse.CaptureDevice} capture (microphone) device so no need to change capture devices.");
|
||||||
|
}
|
||||||
// Change capture Device (if one specified)
|
// Change capture Device (if one specified)
|
||||||
if (shortcutToUse.ChangeCaptureDevice)
|
if (shortcutToUse.ChangeCaptureDevice)
|
||||||
{
|
{
|
||||||
|
logger.Info($"ShortcutRepository/RunShortcut: Changing to the {shortcutToUse.CaptureDevice} capture (microphone) device.");
|
||||||
|
|
||||||
IEnumerable<CoreAudioDevice> captureDevices = _audioController.GetCaptureDevices();
|
IEnumerable<CoreAudioDevice> captureDevices = _audioController.GetCaptureDevices();
|
||||||
foreach (CoreAudioDevice captureDevice in captureDevices)
|
foreach (CoreAudioDevice captureDevice in captureDevices)
|
||||||
{
|
{
|
||||||
@ -512,6 +601,7 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
if (shortcutToUse.SetCaptureVolume)
|
if (shortcutToUse.SetCaptureVolume)
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: Setting {shortcutToUse.CaptureDevice} audio level to {shortcutToUse.CaptureVolume}%.");
|
||||||
Task myTask = new Task(() =>
|
Task myTask = new Task(() =>
|
||||||
{
|
{
|
||||||
captureDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.CaptureVolume));
|
captureDevice.SetVolumeAsync(Convert.ToDouble(shortcutToUse.CaptureVolume));
|
||||||
@ -532,22 +622,52 @@ namespace DisplayMagician
|
|||||||
List<StartProgram> startProgramsToStart = shortcutToUse.StartPrograms.Where(program => program.Enabled == true).OrderBy(program => program.Priority).ToList();
|
List<StartProgram> startProgramsToStart = shortcutToUse.StartPrograms.Where(program => program.Enabled == true).OrderBy(program => program.Priority).ToList();
|
||||||
if (startProgramsToStart.Count > 0)
|
if (startProgramsToStart.Count > 0)
|
||||||
{
|
{
|
||||||
|
logger.Info($"ShortcutRepository/RunShortcut: Starting {startProgramsToStart.Count} programs before the main game or executable");
|
||||||
foreach (StartProgram processToStart in startProgramsToStart)
|
foreach (StartProgram processToStart in startProgramsToStart)
|
||||||
{
|
{
|
||||||
// Start the executable
|
// Start the executable
|
||||||
Console.WriteLine("Starting programs before main game/executable:");
|
logger.Info($"ShortcutRepository/RunShortcut: Starting process {processToStart.Executable}");
|
||||||
|
|
||||||
Console.WriteLine($" - Starting process {processToStart.Executable}");
|
|
||||||
Process process = null;
|
Process process = null;
|
||||||
if (processToStart.ExecutableArgumentsRequired)
|
try
|
||||||
process = System.Diagnostics.Process.Start(processToStart.Executable, processToStart.Arguments);
|
{
|
||||||
else
|
if (processToStart.ExecutableArgumentsRequired)
|
||||||
process = System.Diagnostics.Process.Start(processToStart.Executable);
|
process = System.Diagnostics.Process.Start(processToStart.Executable, processToStart.Arguments);
|
||||||
// Record t
|
else
|
||||||
if (processToStart.CloseOnFinish)
|
process = System.Diagnostics.Process.Start(processToStart.Executable);
|
||||||
startProgramsToStop.Add(process);
|
// Record t
|
||||||
|
if (processToStart.CloseOnFinish)
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: We need to stop {processToStart.Executable} after the main game or executable is closed.");
|
||||||
|
startProgramsToStop.Add(process);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: No need to stop {processToStart.Executable} after the main game or executable is closed, so we'll just leave it running");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Win32Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/RunShortcut: Win32Exception starting process {processToStart.Executable}. Windows complained about something while trying to create a new process.");
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/RunShortcut: Exception starting process {processToStart.Executable}. The object was disposed before we could start the process.");
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/RunShortcut: Win32Exception starting process {processToStart.Executable}. The file wasn't found by DisplayMagician and so we couldn't start it");
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/RunShortcut: Exception starting process {processToStart.Executable}. Method call is invalid for the current state.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: No programs to start before the main game or executable");
|
||||||
|
}
|
||||||
|
|
||||||
// Add a status notification icon in the status area
|
// Add a status notification icon in the status area
|
||||||
// but only if we are going to wait for a process to finish
|
// but only if we are going to wait for a process to finish
|
||||||
@ -564,10 +684,15 @@ namespace DisplayMagician
|
|||||||
// to create a NotifyIncon as MainForm isn't running to create
|
// to create a NotifyIncon as MainForm isn't running to create
|
||||||
// one for us already!
|
// one for us already!
|
||||||
if (notifyIcon == null)
|
if (notifyIcon == null)
|
||||||
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: We need to create a temporary system tray icon as we're running from a shortcut");
|
||||||
temporaryNotifyIcon = true;
|
temporaryNotifyIcon = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (temporaryNotifyIcon)
|
if (temporaryNotifyIcon)
|
||||||
{
|
{
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: Create a temporary system tray icon (user clicked a desktop shortcut)");
|
||||||
|
|
||||||
if (!shortcutToUse.Category.Equals(ShortcutCategory.NoGame))
|
if (!shortcutToUse.Category.Equals(ShortcutCategory.NoGame))
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -590,6 +715,8 @@ namespace DisplayMagician
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: Updating existing system tray icon (we're running a shortcut from within the main application window)");
|
||||||
// If we reach here then we're running the shortcut
|
// If we reach here then we're running the shortcut
|
||||||
// from the ShortcutLibrary window, so we need to
|
// from the ShortcutLibrary window, so we need to
|
||||||
// remember what the text was so we can return it to
|
// remember what the text was so we can return it to
|
||||||
@ -604,12 +731,33 @@ namespace DisplayMagician
|
|||||||
// Now start the main game, and wait if we have to
|
// Now start the main game, and wait if we have to
|
||||||
if (shortcutToUse.Category.Equals(ShortcutCategory.Application))
|
if (shortcutToUse.Category.Equals(ShortcutCategory.Application))
|
||||||
{
|
{
|
||||||
|
logger.Info($"ShortcutRepository/RunShortcut: Starting the main executable that we wanted to run, and that we're going to monitor and watch");
|
||||||
// Start the executable
|
// Start the executable
|
||||||
Process process = null;
|
|
||||||
if (shortcutToUse.ExecutableArgumentsRequired)
|
try
|
||||||
process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath, shortcutToUse.ExecutableArguments);
|
{
|
||||||
else
|
Process process = null;
|
||||||
process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath);
|
if (shortcutToUse.ExecutableArgumentsRequired)
|
||||||
|
process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath, shortcutToUse.ExecutableArguments);
|
||||||
|
else
|
||||||
|
process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath);
|
||||||
|
}
|
||||||
|
catch (Win32Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/RunShortcut: Win32Exception starting main executable process {shortcutToUse.ExecutableNameAndPath}. Windows complained about something while trying to create a new process.");
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/RunShortcut: Exception starting main executable process {shortcutToUse.ExecutableNameAndPath}. The object was disposed before we could start the process.");
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/RunShortcut: Win32Exception starting main executable process {shortcutToUse.ExecutableNameAndPath}. The file wasn't found by DisplayMagician and so we couldn't start it");
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ShortcutRepository/RunShortcut: Exception starting main executable process {shortcutToUse.ExecutableNameAndPath}. Method call is invalid for the current state.");
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out what we want to look for
|
// Figure out what we want to look for
|
||||||
string processNameToLookFor;
|
string processNameToLookFor;
|
||||||
@ -623,6 +771,7 @@ namespace DisplayMagician
|
|||||||
// If we are monitoring a different executable, then lets do get that name ready instead
|
// If we are monitoring a different executable, then lets do get that name ready instead
|
||||||
processNameToLookFor = System.IO.Path.GetFileNameWithoutExtension(shortcutToUse.DifferentExecutableToMonitor);
|
processNameToLookFor = System.IO.Path.GetFileNameWithoutExtension(shortcutToUse.DifferentExecutableToMonitor);
|
||||||
}
|
}
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: Looking for processes with the name {processNameToLookFor} so that we can monitor them and know when they are closed.");
|
||||||
|
|
||||||
// Now look for the thing we're supposed to monitor
|
// Now look for the thing we're supposed to monitor
|
||||||
// and wait until it starts up
|
// and wait until it starts up
|
||||||
@ -636,7 +785,7 @@ namespace DisplayMagician
|
|||||||
// so let's break
|
// so let's break
|
||||||
if (processesToMonitor.Count > 0)
|
if (processesToMonitor.Count > 0)
|
||||||
{
|
{
|
||||||
logger.Debug($"Found {processesToMonitor.Count} '{processNameToLookFor}' processes have started");
|
logger.Debug($"ShortcutRepository/RunShortcut: Found {processesToMonitor.Count} '{processNameToLookFor}' processes to monitor");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,7 +796,7 @@ namespace DisplayMagician
|
|||||||
// make sure we have things to monitor and alert if not
|
// make sure we have things to monitor and alert if not
|
||||||
if (processesToMonitor.Count == 0)
|
if (processesToMonitor.Count == 0)
|
||||||
{
|
{
|
||||||
logger.Error($"No '{processNameToLookFor}' processes found before waiting timeout");
|
logger.Error($"No '{processNameToLookFor}' processes found before waiting timeout. DisplayMagician was unable to find any processes before the {shortcutToUse.StartTimeout} second timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the process to monitor for later
|
// Store the process to monitor for later
|
||||||
@ -663,6 +812,7 @@ namespace DisplayMagician
|
|||||||
}
|
}
|
||||||
Application.DoEvents();
|
Application.DoEvents();
|
||||||
|
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: Creating the Windows Toast to notify the user we're going to wait for the executable {shortcutToUse.ExecutableNameAndPath} to close.");
|
||||||
// Now we want to tell the user we're running an application!
|
// Now we want to tell the user we're running an application!
|
||||||
// Construct the Windows toast content
|
// Construct the Windows toast content
|
||||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||||
@ -686,10 +836,10 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
// if we have things to monitor, then we should start to wait for them
|
// if we have things to monitor, then we should start to wait for them
|
||||||
Console.WriteLine($"Waiting for all {processNameToLookFor} windows to exit.");
|
Console.WriteLine($"Waiting for all {processNameToLookFor} windows to exit.");
|
||||||
logger.Debug($"ShortcutRepository/RunShortcut - waiting for application {processNameToLookFor} to exit.");
|
logger.Debug($"ShortcutRepository/RunShortcut: Waiting for application {processNameToLookFor} to exit.");
|
||||||
if (processesToMonitor.Count > 0)
|
if (processesToMonitor.Count > 0)
|
||||||
{
|
{
|
||||||
logger.Debug($"{processesToMonitor.Count} '{processNameToLookFor}' processes are still running");
|
logger.Debug($"ShortcutRepository/RunShortcut: {processesToMonitor.Count} '{processNameToLookFor}' processes are still running");
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
processesToMonitor = Process.GetProcessesByName(processNameToLookFor).ToList();
|
processesToMonitor = Process.GetProcessesByName(processNameToLookFor).ToList();
|
||||||
@ -697,14 +847,16 @@ namespace DisplayMagician
|
|||||||
// If we have no more processes left then we're done!
|
// If we have no more processes left then we're done!
|
||||||
if (processesToMonitor.Count == 0)
|
if (processesToMonitor.Count == 0)
|
||||||
{
|
{
|
||||||
logger.Debug($"No more '{processNameToLookFor}' processes are still running");
|
logger.Debug($"ShortcutRepository/RunShortcut: No more '{processNameToLookFor}' processes are still running");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Console.WriteLine($"{processNameToLookFor} has exited.");
|
Console.WriteLine($"{processNameToLookFor} has exited.");
|
||||||
logger.Debug($"ShortcutRepository/RunShortcut - Application {processNameToLookFor} has exited.");
|
logger.Debug($"ShortcutRepository/RunShortcut: Executable {processNameToLookFor} has exited.");
|
||||||
|
|
||||||
|
|
||||||
|
logger.Debug($"ShortcutRepository/RunShortcut: Creating a Windows Toast to notify the user that the executable {shortcutToUse.ExecutableNameAndPath} has closed.");
|
||||||
// Tell the user that the application has closed
|
// Tell the user that the application has closed
|
||||||
// Construct the toast content
|
// Construct the toast content
|
||||||
tcBuilder = new ToastContentBuilder()
|
tcBuilder = new ToastContentBuilder()
|
||||||
@ -729,10 +881,11 @@ namespace DisplayMagician
|
|||||||
// If the game is a Steam Game we check for that
|
// If the game is a Steam Game we check for that
|
||||||
if (shortcutToUse.GameLibrary.Equals(SupportedGameLibrary.Steam))
|
if (shortcutToUse.GameLibrary.Equals(SupportedGameLibrary.Steam))
|
||||||
{
|
{
|
||||||
|
|
||||||
// We now need to get the SteamGame info
|
// We now need to get the SteamGame info
|
||||||
SteamGame steamGameToRun = SteamLibrary.GetSteamGame(shortcutToUse.GameAppId);
|
SteamGame steamGameToRun = SteamLibrary.GetSteamGame(shortcutToUse.GameAppId);
|
||||||
|
|
||||||
|
logger.Info($"ShortcutRepository/RunShortcut: Starting the {steamGameToRun.Name} Steam Game, and then we're going to monitor it to wait for it to close.");
|
||||||
|
|
||||||
// If the GameAppID matches a Steam game, then lets run it
|
// If the GameAppID matches a Steam game, then lets run it
|
||||||
if (steamGameToRun is SteamGame)
|
if (steamGameToRun is SteamGame)
|
||||||
{
|
{
|
||||||
@ -847,6 +1000,8 @@ namespace DisplayMagician
|
|||||||
// We now need to get the Uplay Game info
|
// We now need to get the Uplay Game info
|
||||||
UplayGame uplayGameToRun = UplayLibrary.GetUplayGame(shortcutToUse.GameAppId);
|
UplayGame uplayGameToRun = UplayLibrary.GetUplayGame(shortcutToUse.GameAppId);
|
||||||
|
|
||||||
|
logger.Info($"ShortcutRepository/RunShortcut: Starting the {uplayGameToRun.Name} Uplay Game, and then we're going to monitor it to wait for it to close.");
|
||||||
|
|
||||||
// If the GameAppID matches a Uplay game, then lets run it
|
// If the GameAppID matches a Uplay game, then lets run it
|
||||||
if (uplayGameToRun is UplayGame)
|
if (uplayGameToRun is UplayGame)
|
||||||
{
|
{
|
||||||
|
@ -305,7 +305,7 @@ namespace DisplayMagician.UIForms
|
|||||||
// Lets update the rest of the profile screen too
|
// Lets update the rest of the profile screen too
|
||||||
lbl_profile_shown.Text = txt_profile_save_name.Text;
|
lbl_profile_shown.Text = txt_profile_save_name.Text;
|
||||||
|
|
||||||
// And we also need to go through the Shortcuts in the library and rename them!
|
// And we also need to go through the any Shortcuts that use the profile and rename them too!
|
||||||
ShortcutRepository.RenameShortcutProfile(_selectedProfile);
|
ShortcutRepository.RenameShortcutProfile(_selectedProfile);
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ namespace DisplayMagician
|
|||||||
{
|
{
|
||||||
class ProfileMustExistValidator : IArgumentValidator
|
class ProfileMustExistValidator : IArgumentValidator
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public ValidationResult GetValidationResult(CommandArgument argumentProfileName, ValidationContext context)
|
public ValidationResult GetValidationResult(CommandArgument argumentProfileName, ValidationContext context)
|
||||||
{
|
{
|
||||||
// This validator only runs if there is a value
|
// This validator only runs if there is a value
|
||||||
@ -25,6 +28,7 @@ namespace DisplayMagician
|
|||||||
// Try to find the Profile Name
|
// Try to find the Profile Name
|
||||||
if (!ProfileRepository.ContainsProfile(profileName))
|
if (!ProfileRepository.ContainsProfile(profileName))
|
||||||
{
|
{
|
||||||
|
logger.Error($"ProfileMustExistValidator/GetValidationResult: Couldn't find Profile Name or ID supplied via command line: '{profileName}'. Please check the Profile Name or ID you supplied on the command line is correct.");
|
||||||
return new ValidationResult($"Couldn't find Profile Name or ID supplied via command line: '{profileName}'. Please check the Profile Name or ID you supplied on the command line is correct.");
|
return new ValidationResult($"Couldn't find Profile Name or ID supplied via command line: '{profileName}'. Please check the Profile Name or ID you supplied on the command line is correct.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,6 +40,8 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
class ShortcutMustExistValidator : IArgumentValidator
|
class ShortcutMustExistValidator : IArgumentValidator
|
||||||
{
|
{
|
||||||
|
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public ValidationResult GetValidationResult(CommandArgument argumentShortcutName, ValidationContext context)
|
public ValidationResult GetValidationResult(CommandArgument argumentShortcutName, ValidationContext context)
|
||||||
{
|
{
|
||||||
// This validator only runs if there is a string provided
|
// This validator only runs if there is a string provided
|
||||||
@ -45,6 +51,7 @@ namespace DisplayMagician
|
|||||||
// Check if the UUID or ShortcutName are provided
|
// Check if the UUID or ShortcutName are provided
|
||||||
if (!ShortcutRepository.ContainsShortcut(shortcutName))
|
if (!ShortcutRepository.ContainsShortcut(shortcutName))
|
||||||
{
|
{
|
||||||
|
logger.Error($"ProfileMustExistValidator/GetValidationResult: Couldn't find Shortcut Name supplied via command line: '{shortcutName}'. Please check the Shortcut Name you supplied on the command line is correct.");
|
||||||
return new ValidationResult($"Couldn't find Shortcut Name supplied via command line: '{shortcutName}'. Please check the Shortcut Name you supplied on the command line is correct.");
|
return new ValidationResult($"Couldn't find Shortcut Name supplied via command line: '{shortcutName}'. Please check the Shortcut Name you supplied on the command line is correct.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +64,8 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
class FileOptionMustExistValidator : IOptionValidator
|
class FileOptionMustExistValidator : IOptionValidator
|
||||||
{
|
{
|
||||||
|
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public ValidationResult GetValidationResult(CommandOption optionFullFileName, ValidationContext context)
|
public ValidationResult GetValidationResult(CommandOption optionFullFileName, ValidationContext context)
|
||||||
{
|
{
|
||||||
// This validator only runs if there is a string provided
|
// This validator only runs if there is a string provided
|
||||||
@ -66,6 +75,7 @@ namespace DisplayMagician
|
|||||||
// Check that the file exists
|
// Check that the file exists
|
||||||
if (!File.Exists(fileNameAndPath))
|
if (!File.Exists(fileNameAndPath))
|
||||||
{
|
{
|
||||||
|
logger.Error($"ProfileMustExistValidator/GetValidationResult: Couldn't find the file '{optionFullFileName.Value()}' supplied to '{optionFullFileName.LongName}'. Please check you specified the full path to the file on the command line.");
|
||||||
return new ValidationResult($"Couldn't find the file '{optionFullFileName.Value()}' supplied to '{optionFullFileName.LongName}'. Please check you specified the full path to the file on the command line.");
|
return new ValidationResult($"Couldn't find the file '{optionFullFileName.Value()}' supplied to '{optionFullFileName.LongName}'. Please check you specified the full path to the file on the command line.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +85,8 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
class FileArgumentMustExistValidator : IArgumentValidator
|
class FileArgumentMustExistValidator : IArgumentValidator
|
||||||
{
|
{
|
||||||
|
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public ValidationResult GetValidationResult(CommandArgument argumentFullFileName, ValidationContext context)
|
public ValidationResult GetValidationResult(CommandArgument argumentFullFileName, ValidationContext context)
|
||||||
{
|
{
|
||||||
// This validator only runs if there is a string provided
|
// This validator only runs if there is a string provided
|
||||||
@ -84,6 +96,7 @@ namespace DisplayMagician
|
|||||||
// Check that the file exists
|
// Check that the file exists
|
||||||
if (!File.Exists(fileNameAndPath))
|
if (!File.Exists(fileNameAndPath))
|
||||||
{
|
{
|
||||||
|
logger.Error($"ProfileMustExistValidator/GetValidationResult: Couldn't find the file '{argumentFullFileName.Value}' supplied to '{argumentFullFileName.Name}'. Please check you specified the full path to the file on the command line.");
|
||||||
return new ValidationResult($"Couldn't find the file '{argumentFullFileName.Value}' supplied to '{argumentFullFileName.Name}'. Please check you specified the full path to the file on the command line.");
|
return new ValidationResult($"Couldn't find the file '{argumentFullFileName.Value}' supplied to '{argumentFullFileName.Name}'. Please check you specified the full path to the file on the command line.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user