Working Single Instance

Works fine, but still locks the UI. There is the potential for a race condition now as we have multiple pathways to run a shortcut or change the display profile. Next step is to stop that from being a problem.
This commit is contained in:
Terry MacDonald 2022-01-03 21:39:19 +13:00
parent 35fe7dc36d
commit f6410de1ca
3 changed files with 63 additions and 28 deletions

View File

@ -683,7 +683,7 @@ namespace DisplayMagician {
return 0;
}
private static void CreateProfile()
public static void CreateProfile()
{
logger.Debug($"Program/CreateProfile: Starting");
@ -796,9 +796,9 @@ namespace DisplayMagician {
}
// ReSharper disable once CyclomaticComplexity
private static void RunShortcut(string shortcutUUID)
public static void RunShortcut(string shortcutUUID)
{
logger.Debug($"Program/RunShortcut: Starting");
logger.Debug($"Program/RunShortcut: Running shortcut {shortcutUUID}");
ShortcutItem shortcutToRun = null;
@ -806,20 +806,6 @@ namespace DisplayMagician {
if (ProgramSettings.LoadSettings().ShowSplashScreen && AppSplashScreen != null && !AppSplashScreen.Disposing && !AppSplashScreen.IsDisposed)
AppSplashScreen.Invoke(new Action(() => AppSplashScreen.Close()));
// Check there is only one version of this application so we won't
// mess with another monitoring session
/*if (
IPCClient.QueryAll()
.Any(
client =>
client.Status == InstanceStatus.Busy ||
client.Status == InstanceStatus.OnHold))
{
throw new Exception(
Language
.Another_instance_of_this_program_is_in_working_state_Please_close_other_instances_before_trying_to_switch_profile);
}*/
// Match the ShortcutName to the actual shortcut listed in the shortcut library
// And error if we can't find it.
if (ShortcutRepository.ContainsShortcut(shortcutUUID))
@ -827,19 +813,16 @@ namespace DisplayMagician {
// make sure we trim the "" if there are any
shortcutUUID = shortcutUUID.Trim('"');
shortcutToRun = ShortcutRepository.GetShortcut(shortcutUUID);
if (shortcutToRun is ShortcutItem)
{
ShortcutRepository.RunShortcut(shortcutToRun);
}
}
else
{
throw new Exception(Language.Cannot_find_shortcut_in_library);
}
if (shortcutToRun is ShortcutItem)
{
ShortcutRepository.RunShortcut(shortcutToRun);
}
//IPCService.GetInstance().Status = InstanceStatus.Busy;
}
public static bool IsValidFilename(string testName)
@ -854,7 +837,7 @@ namespace DisplayMagician {
public static void RunProfile(string profileName)
{
logger.Trace($"Program/RunProfile: Starting");
logger.Trace($"Program/RunProfile: Running profile {profileName}");
// Close the splash screen
if (ProgramSettings.LoadSettings().ShowSplashScreen && AppSplashScreen != null && !AppSplashScreen.Disposing && !AppSplashScreen.IsDisposed)

View File

@ -26,8 +26,8 @@ using System.Resources;
[assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
// Version information
[assembly: AssemblyVersion("2.1.5.19")]
[assembly: AssemblyFileVersion("2.1.5.19")]
[assembly: AssemblyVersion("2.1.5.20")]
[assembly: AssemblyFileVersion("2.1.5.20")]
[assembly: NeutralResourcesLanguageAttribute( "en" )]
[assembly: CLSCompliant(true)]

View File

@ -9,6 +9,7 @@ using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Xml.Serialization;
@ -33,6 +34,8 @@ namespace DisplayMagician
private static Action<string[]> _otherInstanceCallback;
private static readonly object _namedPiperServerThreadLock = new object();
private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
//private static string GetMutexName() => $@"Mutex_{Environment.UserDomainName}_{Environment.UserName}_{UniqueName}";
//private static string GetPipeName() => $@"Pipe_{Environment.UserDomainName}_{Environment.UserName}_{UniqueName}";
private static string GetMutexName() => $@"Mutex_{UniqueName}";
@ -40,7 +43,56 @@ namespace DisplayMagician
public static void executeAnActionCallback(string[] args)
{
MessageBox.Show("got data: " + String.Join(" ",args));
logger.Trace($"SingleInstance/executeAnActionCallback: Received data from another DisplayMagician instance: {String.Join(" ",args)}");
// Now we want to figure out if it's an actionable command
// The command is in an array, and the first item is the full path to the displaymagician instance that ran.
// We only want to see if we should action this command if it has more args than just the single file path
if (args.Length > 1)
{
// Setup a regex to match the UUID format we use
Regex uuid = new Regex("[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}");
// Now we check for the three commandline parameters that we support
switch (args[1])
{
case "RunShortcut":
logger.Trace($"SingleInstance/executeAnActionCallback: Other DisplayMagician instance provided the RunShortcut command: '{args[1]} {args[2]}'");
if (uuid.IsMatch(args[2]))
{
Program.RunShortcut(args[2]);
}
else
{
logger.Warn($"SingleInstance/executeAnActionCallback: Other DisplayMagician instance provided an invalid shortcut UUID to the RunShortcut command: '{args[2]}'");
}
break;
case "ChangeProfile":
logger.Trace($"SingleInstance/executeAnActionCallback: Other DisplayMagician instance provided the ChangeProfile command: '{args[1]} {args[2]}'");
if (uuid.IsMatch(args[2]))
{
Program.RunProfile(args[2]);
}
else
{
logger.Warn($"SingleInstance/executeAnActionCallback: Other DisplayMagician instance provided an invalid profile UUID to the ChangeProfile command: '{args[2]}'");
}
break;
case "CreateProfile":
logger.Trace($"SingleInstance/executeAnActionCallback: Other DisplayMagician instance provided the CreateProfile command: '{args[1]} {args[2]}'");
Program.CreateProfile();
break;
default:
logger.Warn($"SingleInstance/executeAnActionCallback: Other DisplayMagician instance provided an unsupported command: '{args[1]}'");
break;
}
}
else if (args.Length == 1)
{
logger.Trace($"SingleInstance/executeAnActionCallback: Other DisplayMagician instance didn't provide any commandline arguments, only the path '{args[0]}'");
}
else
{
logger.Warn($"SingleInstance/executeAnActionCallback: Other DisplayMagician instance didn't provide any commandline arguments at all. THat's not supposed to happen.");
}
}