mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
[WIP] Moving Shortcut run logic to repo
Moved the shortcut running logic from the main Program into the ShortcutRepository so that it can be used from the Shortcut Library UI as well as from the commandline. It's marked as WIP because I also moved the ApplyingChangesForm and accompanying ApplyTopos/ApplyProfiles logic and I broke it. It needs refactoring and hopefully simplifying but I need to work on that next!
This commit is contained in:
parent
add7d0ff14
commit
c358bc9087
@ -333,84 +333,7 @@ namespace HeliosPlus.Shared
|
||||
}
|
||||
return uncheckedFilename;
|
||||
}
|
||||
|
||||
public void ApplyTopos()
|
||||
{
|
||||
Debug.Print("_applyTopos()");
|
||||
try
|
||||
{
|
||||
var surroundTopologies =
|
||||
Viewports.SelectMany(viewport => viewport.TargetDisplays)
|
||||
.Select(target => target.SurroundTopology)
|
||||
.Where(topology => topology != null)
|
||||
.Select(topology => topology.ToGridTopology())
|
||||
.ToArray();
|
||||
|
||||
if (surroundTopologies.Length == 0)
|
||||
{
|
||||
var currentTopologies = GridTopology.GetGridTopologies();
|
||||
|
||||
if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1))
|
||||
{
|
||||
surroundTopologies =
|
||||
GridTopology.GetGridTopologies()
|
||||
.SelectMany(topology => topology.Displays)
|
||||
.Select(displays => new GridTopology(1, 1, new[] { displays }))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (surroundTopologies.Length > 0)
|
||||
{
|
||||
GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ProfileItem/ApplyTopos exception: {ex.Message}: {ex.InnerException}");
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyPathInfos()
|
||||
{
|
||||
Debug.Print("_applyPathInfos()");
|
||||
if (!IsPossible)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Problem applying the '{Name}' Display Profile! The display configuration changed since this profile is created. Please re-create this profile.");
|
||||
}
|
||||
|
||||
var pathInfos = Viewports.Select(viewport => viewport.ToPathInfo()).Where(info => info != null).ToArray();
|
||||
PathInfo.ApplyPathInfos(pathInfos, true, true, true);
|
||||
}
|
||||
|
||||
public IDictionary<string, Action> applyProfileActions()
|
||||
{
|
||||
var dict = new Dictionary<string, Action>()
|
||||
{
|
||||
{ "Applying_Topos", ApplyTopos },
|
||||
{ "Applying_Paths", ApplyPathInfos }
|
||||
};
|
||||
return dict;
|
||||
}
|
||||
|
||||
public IDictionary<string, string> applyProfileMsgs()
|
||||
{
|
||||
var dict = new Dictionary<string, string>()
|
||||
{
|
||||
{ "Applying_Topos", Language.Applying_First_Message },
|
||||
{ "Applying_Paths", Language.Applying_Second_Message }
|
||||
};
|
||||
return dict;
|
||||
}
|
||||
|
||||
public List<string> applyProfileSequence()
|
||||
{
|
||||
var list = new List<string>() { "Applying_Topos", "Applying_Paths" };
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Custom comparer for the Profile class
|
||||
|
@ -21,6 +21,9 @@ using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Resources;
|
||||
using System.Net.NetworkInformation;
|
||||
using NvAPIWrapper.Mosaic;
|
||||
using NvAPIWrapper.Native.Mosaic;
|
||||
|
||||
namespace HeliosPlus.Shared
|
||||
{
|
||||
@ -527,7 +530,8 @@ namespace HeliosPlus.Shared
|
||||
Name = "Current Display Profile",
|
||||
Viewports = PathInfo.GetActivePaths().Select(info => new ProfileViewport(info)).ToArray()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool ApplyProfile(ProfileItem profile)
|
||||
{
|
||||
@ -536,14 +540,14 @@ namespace HeliosPlus.Shared
|
||||
|
||||
Debug.Print("Begin profile change");
|
||||
Thread.Sleep(2000);
|
||||
profile.ApplyTopos();
|
||||
ApplyTopos(profile);
|
||||
|
||||
Debug.Print("Finished setting topologies");
|
||||
Debug.Print("Sleep");
|
||||
Thread.Sleep(18000);
|
||||
Debug.Print("Awake");
|
||||
|
||||
profile.ApplyPathInfos();
|
||||
ApplyPathInfos(profile);
|
||||
|
||||
Debug.Print("Applying pathInfos");
|
||||
Debug.Print("Sleep");
|
||||
@ -565,6 +569,83 @@ namespace HeliosPlus.Shared
|
||||
}
|
||||
}
|
||||
|
||||
public static void ApplyTopos(ProfileItem profile)
|
||||
{
|
||||
Debug.Print("_applyTopos()");
|
||||
try
|
||||
{
|
||||
var surroundTopologies =
|
||||
profile.Viewports.SelectMany(viewport => viewport.TargetDisplays)
|
||||
.Select(target => target.SurroundTopology)
|
||||
.Where(topology => topology != null)
|
||||
.Select(topology => topology.ToGridTopology())
|
||||
.ToArray();
|
||||
|
||||
if (surroundTopologies.Length == 0)
|
||||
{
|
||||
var currentTopologies = GridTopology.GetGridTopologies();
|
||||
|
||||
if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1))
|
||||
{
|
||||
surroundTopologies =
|
||||
GridTopology.GetGridTopologies()
|
||||
.SelectMany(topology => topology.Displays)
|
||||
.Select(displays => new GridTopology(1, 1, new[] { displays }))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (surroundTopologies.Length > 0)
|
||||
{
|
||||
GridTopology.SetGridTopologies(surroundTopologies, SetDisplayTopologyFlag.MaximizePerformance);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ProfileItem/ApplyTopos exception: {ex.Message}: {ex.InnerException}");
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public static void ApplyPathInfos(ProfileItem profile)
|
||||
{
|
||||
Debug.Print("_applyPathInfos()");
|
||||
if (!profile.IsPossible)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Problem applying the '{profile.Name}' Display Profile! The display configuration changed since this profile is created. Please re-create this profile.");
|
||||
}
|
||||
|
||||
var pathInfos = profile.Viewports.Select(viewport => viewport.ToPathInfo()).Where(info => info != null).ToArray();
|
||||
PathInfo.ApplyPathInfos(pathInfos, true, true, true);
|
||||
}
|
||||
|
||||
/* public static IDictionary<string, Action> applyProfileActions(ProfileItem profile)
|
||||
{
|
||||
var dict = new Dictionary<string, Action>()
|
||||
{
|
||||
{ "Applying_Topos", ApplyTopos(profile) },
|
||||
{ "Applying_Paths", ApplyPathInfos(profile) }
|
||||
};
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static IDictionary<string, string> applyProfileMsgs()
|
||||
{
|
||||
var dict = new Dictionary<string, string>()
|
||||
{
|
||||
{ "Applying_Topos", Language.Applying_First_Message },
|
||||
{ "Applying_Paths", Language.Applying_Second_Message }
|
||||
};
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static List<string> applyProfileSequence()
|
||||
{
|
||||
var list = new List<string>() { "Applying_Topos", "Applying_Paths" };
|
||||
return list;
|
||||
}*/
|
||||
|
||||
public static bool IsValidFilename(string testName)
|
||||
{
|
||||
string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidFileNameChars());
|
||||
|
@ -252,7 +252,6 @@ namespace HeliosPlus {
|
||||
// ReSharper disable once CyclomaticComplexity
|
||||
private static void RunShortcut(string shortcutUUID)
|
||||
{
|
||||
ProfileItem rollbackProfile = ProfileRepository.CurrentProfile;
|
||||
ShortcutItem shortcutToRun = null;
|
||||
|
||||
// Check there is only one version of this application so we won't
|
||||
@ -282,276 +281,16 @@ namespace HeliosPlus {
|
||||
throw new Exception(Language.Cannot_find_shortcut_in_library);
|
||||
}
|
||||
|
||||
// Do some validation to make sure the shortcut is sensible
|
||||
// And that we have enough to try and action within the shortcut
|
||||
// (in other words check everything in the shortcut is still valid)
|
||||
(bool valid, string reason) = shortcutToRun.IsValid();
|
||||
if (!valid)
|
||||
if (shortcutToRun is ShortcutItem)
|
||||
{
|
||||
throw new Exception(string.Format("Unable to run the shortcut '{0}': {1}",shortcutToRun.Name,reason));
|
||||
ShortcutRepository.RunShortcut(shortcutToRun);
|
||||
}
|
||||
|
||||
// Try to change to the wanted profile
|
||||
if (!SwitchProfile(shortcutToRun.ProfileToUse))
|
||||
{
|
||||
throw new Exception(Language.Cannot_change_active_profile);
|
||||
}
|
||||
|
||||
// Now run the pre-start applications
|
||||
// TODO: Add the prestart applications
|
||||
|
||||
// Now start the main game, and wait if we have to
|
||||
if (shortcutToRun.Category.Equals(ShortcutCategory.Application))
|
||||
{
|
||||
// Start the executable
|
||||
Process process = null;
|
||||
if (shortcutToRun.ExecutableArgumentsRequired)
|
||||
process = System.Diagnostics.Process.Start(shortcutToRun.ExecutableNameAndPath, shortcutToRun.ExecutableArguments);
|
||||
else
|
||||
process = System.Diagnostics.Process.Start(shortcutToRun.ExecutableNameAndPath);
|
||||
|
||||
// Create a list of processes to monitor
|
||||
Process[] processesToMonitor = Array.Empty<Process>();
|
||||
|
||||
// Work out if we are monitoring another process other than the main executable
|
||||
if (shortcutToRun.ProcessNameToMonitorUsesExecutable)
|
||||
{
|
||||
// If we are monitoring the same executable we started, then lets do that
|
||||
processesToMonitor = new[] { process };
|
||||
}
|
||||
else
|
||||
{
|
||||
// Now wait a little while for all the processes we want to monitor to start up
|
||||
var ticks = 0;
|
||||
while (ticks < shortcutToRun.ExecutableTimeout * 1000)
|
||||
{
|
||||
// Look for the processes with the ProcessName we want (which in Windows is the filename without the extension)
|
||||
processesToMonitor = System.Diagnostics.Process.GetProcessesByName(Path.GetFileNameWithoutExtension(shortcutToRun.DifferentExecutableToMonitor));
|
||||
|
||||
// TODO: Fix this logic error that will only ever wait for the first process....
|
||||
if (processesToMonitor.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(300);
|
||||
ticks += 300;
|
||||
}
|
||||
|
||||
// If none started up before the timeout, then ignore the
|
||||
if (processesToMonitor.Length == 0)
|
||||
{
|
||||
processesToMonitor = new[] { process };
|
||||
}
|
||||
}
|
||||
|
||||
// Store the process to monitor for later
|
||||
IPCService.GetInstance().HoldProcessId = processesToMonitor.FirstOrDefault()?.Id ?? 0;
|
||||
IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
|
||||
// Add a status notification icon in the status area
|
||||
NotifyIcon notify = null;
|
||||
try
|
||||
{
|
||||
notify = new NotifyIcon
|
||||
{
|
||||
Icon = Properties.Resources.HeliosPlus,
|
||||
Text = string.Format(
|
||||
Language.Waiting_for_the_0_to_terminate,
|
||||
processesToMonitor[0].ProcessName),
|
||||
Visible = true
|
||||
};
|
||||
Application.DoEvents();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Program/SwitchToExecutable exception: {ex.Message}: {ex.InnerException}");
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Wait for the monitored process to exit
|
||||
foreach (var p in processesToMonitor)
|
||||
{
|
||||
try
|
||||
{
|
||||
p.WaitForExit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Program/SwitchToExecutable exception 2: {ex.Message}: {ex.InnerException}");
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the status notification icon from the status area
|
||||
// once we've existed the game
|
||||
if (notify != null)
|
||||
{
|
||||
notify.Visible = false;
|
||||
notify.Dispose();
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
}
|
||||
else if (shortcutToRun.Category.Equals(ShortcutCategory.Game))
|
||||
{
|
||||
// If the game is a Steam Game we check for that
|
||||
if (shortcutToRun.GameLibrary.Equals(SupportedGameLibrary.Steam))
|
||||
{
|
||||
// We now need to get the SteamGame info
|
||||
SteamGame steamGameToRun = SteamLibrary.GetSteamGame(shortcutToRun.GameAppId);
|
||||
|
||||
// If the GameAppID matches a Steam game, then lets run it
|
||||
if (steamGameToRun is SteamGame)
|
||||
{
|
||||
// Prepare to start the steam game using the URI interface
|
||||
// as used by Steam for it's own desktop shortcuts.
|
||||
var address = $"steam://rungameid/{steamGameToRun.GameId}";
|
||||
if (shortcutToRun.GameArgumentsRequired)
|
||||
{
|
||||
address += "/" + shortcutToRun.GameArguments;
|
||||
}
|
||||
|
||||
// Start the URI Handler to run Steam
|
||||
var steamProcess = System.Diagnostics.Process.Start(address);
|
||||
|
||||
// Wait for Steam game to update if needed
|
||||
var ticks = 0;
|
||||
while (ticks < shortcutToRun.GameTimeout * 1000)
|
||||
{
|
||||
if (steamGameToRun.IsRunning)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(300);
|
||||
|
||||
if (!steamGameToRun.IsUpdating)
|
||||
{
|
||||
ticks += 300;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the Steam Process ID for later
|
||||
IPCService.GetInstance().HoldProcessId = steamProcess?.Id ?? 0;
|
||||
IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
|
||||
// Add a status notification icon in the status area
|
||||
NotifyIcon notify = null;
|
||||
try
|
||||
{
|
||||
notify = new NotifyIcon
|
||||
{
|
||||
Icon = Properties.Resources.HeliosPlus,
|
||||
Text = string.Format(
|
||||
Language.Waiting_for_the_0_to_terminate,
|
||||
steamGameToRun.GameName),
|
||||
Visible = true
|
||||
};
|
||||
Application.DoEvents();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Program/SwitchToSteamGame exception: {ex.Message}: {ex.InnerException}");
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Wait for the game to exit
|
||||
if (steamGameToRun.IsRunning)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (!steamGameToRun.IsRunning)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the status notification icon from the status area
|
||||
// once we've existed the game
|
||||
if (notify != null)
|
||||
{
|
||||
notify.Visible = false;
|
||||
notify.Dispose();
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// If the game is a Uplay Game we check for that
|
||||
/*else if (GameLibrary.Equals(SupportedGameLibrary.Uplay))
|
||||
{
|
||||
// We need to look up details about the game
|
||||
if (!UplayGame.IsInstalled(GameAppId))
|
||||
{
|
||||
return (false, string.Format("The Uplay Game with AppID '{0}' is not installed on this computer.", GameAppId));
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
IPCService.GetInstance().Status = InstanceStatus.Busy;
|
||||
|
||||
// Change back to the original profile if it is different
|
||||
if (!ProfileRepository.IsActiveProfile(rollbackProfile))
|
||||
{
|
||||
if (!SwitchProfile(rollbackProfile))
|
||||
{
|
||||
throw new Exception(Language.Cannot_change_active_profile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal static bool SwitchProfile(ProfileItem profile)
|
||||
{
|
||||
// If we're already on the wanted profile then no need to change!
|
||||
if (ProfileRepository.IsActiveProfile(profile))
|
||||
return true;
|
||||
|
||||
var instanceStatus = IPCService.GetInstance().Status;
|
||||
|
||||
try
|
||||
{
|
||||
IPCService.GetInstance().Status = InstanceStatus.Busy;
|
||||
var failed = false;
|
||||
|
||||
if (new ApplyingChangesForm(() =>
|
||||
{
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
if (!(ProfileRepository.ApplyProfile(profile)))
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
}, 3, 30).ShowDialog() !=
|
||||
DialogResult.Cancel)
|
||||
{
|
||||
if (failed)
|
||||
{
|
||||
throw new Exception(Language.Profile_is_invalid_or_not_possible_to_apply);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
IPCService.GetInstance().Status = instanceStatus;
|
||||
}
|
||||
}
|
||||
|
||||
private static void EditProfile(ProfileItem profile)
|
||||
/* private static void EditProfile(ProfileItem profile)
|
||||
{
|
||||
// Get the status of the thing
|
||||
IPCService.GetInstance().Status = InstanceStatus.User;
|
||||
@ -562,7 +301,7 @@ namespace HeliosPlus {
|
||||
// Then we close down as we're only here to edit one profile
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
*/
|
||||
public static bool IsValidFilename(string testName)
|
||||
{
|
||||
string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidFileNameChars());
|
||||
@ -573,7 +312,7 @@ namespace HeliosPlus {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string GetValidFilename(string uncheckedFilename)
|
||||
/* public static string GetValidFilename(string uncheckedFilename)
|
||||
{
|
||||
string invalid = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
|
||||
foreach (char c in invalid)
|
||||
@ -581,6 +320,6 @@ namespace HeliosPlus {
|
||||
uncheckedFilename = uncheckedFilename.Replace(c.ToString(), "");
|
||||
}
|
||||
return uncheckedFilename;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
@ -20,6 +20,10 @@ using System.Windows.Forms;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using System.Text.RegularExpressions;
|
||||
using IWshRuntimeLibrary;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using HeliosPlus.InterProcess;
|
||||
using HeliosPlus.UIForms;
|
||||
|
||||
namespace HeliosPlus
|
||||
{
|
||||
@ -662,6 +666,9 @@ namespace HeliosPlus
|
||||
return shortcutFileName != null && System.IO.File.Exists(shortcutFileName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void AutoSuggestShortcutName()
|
||||
{
|
||||
if (AutoName && _profileToUse is ProfileItem)
|
||||
|
@ -1,7 +1,12 @@
|
||||
using HeliosPlus.Shared;
|
||||
using HeliosPlus.GameLibraries;
|
||||
using HeliosPlus.InterProcess;
|
||||
using HeliosPlus.Resources;
|
||||
using HeliosPlus.Shared;
|
||||
using HeliosPlus.UIForms;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.IconLib;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@ -9,6 +14,7 @@ using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
@ -434,6 +440,278 @@ namespace HeliosPlus
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ReSharper disable once CyclomaticComplexity
|
||||
public static void RunShortcut(ShortcutItem shortcutToUse)
|
||||
{
|
||||
// Do some validation to make sure the shortcut is sensible
|
||||
// And that we have enough to try and action within the shortcut
|
||||
// (in other words check everything in the shortcut is still valid)
|
||||
(bool valid, string reason) = shortcutToUse.IsValid();
|
||||
if (!valid)
|
||||
{
|
||||
throw new Exception(string.Format("Unable to run the shortcut '{0}': {1}", shortcutToUse.Name, reason));
|
||||
}
|
||||
|
||||
// Remember the profile we are on now
|
||||
ProfileItem rollbackProfile = ProfileRepository.CurrentProfile;
|
||||
|
||||
// Try to change to the wanted profile
|
||||
if (!ProfileRepository.ApplyProfile(shortcutToUse.ProfileToUse))
|
||||
{
|
||||
throw new Exception(Language.Cannot_change_active_profile);
|
||||
}
|
||||
|
||||
// Now run the pre-start applications
|
||||
// TODO: Add the prestart applications
|
||||
|
||||
// Now start the main game, and wait if we have to
|
||||
if (shortcutToUse.Category.Equals(ShortcutCategory.Application))
|
||||
{
|
||||
// Start the executable
|
||||
Process process = null;
|
||||
if (shortcutToUse.ExecutableArgumentsRequired)
|
||||
process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath, shortcutToUse.ExecutableArguments);
|
||||
else
|
||||
process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath);
|
||||
|
||||
// Create a list of processes to monitor
|
||||
Process[] processesToMonitor = Array.Empty<Process>();
|
||||
|
||||
// Work out if we are monitoring another process other than the main executable
|
||||
if (shortcutToUse.ProcessNameToMonitorUsesExecutable)
|
||||
{
|
||||
// If we are monitoring the same executable we started, then lets do that
|
||||
processesToMonitor = new[] { process };
|
||||
}
|
||||
else
|
||||
{
|
||||
// Now wait a little while for all the processes we want to monitor to start up
|
||||
var ticks = 0;
|
||||
while (ticks < shortcutToUse.ExecutableTimeout * 1000)
|
||||
{
|
||||
// Look for the processes with the ProcessName we want (which in Windows is the filename without the extension)
|
||||
processesToMonitor = System.Diagnostics.Process.GetProcessesByName(Path.GetFileNameWithoutExtension(shortcutToUse.DifferentExecutableToMonitor));
|
||||
|
||||
// TODO: Fix this logic error that will only ever wait for the first process....
|
||||
if (processesToMonitor.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(300);
|
||||
ticks += 300;
|
||||
}
|
||||
|
||||
// If none started up before the timeout, then ignore the
|
||||
if (processesToMonitor.Length == 0)
|
||||
{
|
||||
processesToMonitor = new[] { process };
|
||||
}
|
||||
}
|
||||
|
||||
// Store the process to monitor for later
|
||||
IPCService.GetInstance().HoldProcessId = processesToMonitor.FirstOrDefault()?.Id ?? 0;
|
||||
IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
|
||||
// Add a status notification icon in the status area
|
||||
NotifyIcon notify = null;
|
||||
try
|
||||
{
|
||||
notify = new NotifyIcon
|
||||
{
|
||||
Icon = Properties.Resources.HeliosPlus,
|
||||
Text = string.Format(
|
||||
Language.Waiting_for_the_0_to_terminate,
|
||||
processesToMonitor[0].ProcessName),
|
||||
Visible = true
|
||||
};
|
||||
Application.DoEvents();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ShortcutItem/Run exception: {ex.Message}: {ex.InnerException}");
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Wait for the monitored process to exit
|
||||
foreach (var p in processesToMonitor)
|
||||
{
|
||||
try
|
||||
{
|
||||
p.WaitForExit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ShortcutItem/Run exception 2: {ex.Message}: {ex.InnerException}");
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the status notification icon from the status area
|
||||
// once we've existed the game
|
||||
if (notify != null)
|
||||
{
|
||||
notify.Visible = false;
|
||||
notify.Dispose();
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
}
|
||||
else if (shortcutToUse.Category.Equals(ShortcutCategory.Game))
|
||||
{
|
||||
// If the game is a Steam Game we check for that
|
||||
if (shortcutToUse.GameLibrary.Equals(SupportedGameLibrary.Steam))
|
||||
{
|
||||
// We now need to get the SteamGame info
|
||||
SteamGame steamGameToRun = SteamLibrary.GetSteamGame(shortcutToUse.GameAppId);
|
||||
|
||||
// If the GameAppID matches a Steam game, then lets run it
|
||||
if (steamGameToRun is SteamGame)
|
||||
{
|
||||
// Prepare to start the steam game using the URI interface
|
||||
// as used by Steam for it's own desktop shortcuts.
|
||||
var address = $"steam://rungameid/{steamGameToRun.GameId}";
|
||||
if (shortcutToUse.GameArgumentsRequired)
|
||||
{
|
||||
address += "/" + shortcutToUse.GameArguments;
|
||||
}
|
||||
|
||||
// Start the URI Handler to run Steam
|
||||
var steamProcess = System.Diagnostics.Process.Start(address);
|
||||
|
||||
// Wait for Steam game to update if needed
|
||||
var ticks = 0;
|
||||
while (ticks < shortcutToUse.GameTimeout * 1000)
|
||||
{
|
||||
if (steamGameToRun.IsRunning)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(300);
|
||||
|
||||
if (!steamGameToRun.IsUpdating)
|
||||
{
|
||||
ticks += 300;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the Steam Process ID for later
|
||||
IPCService.GetInstance().HoldProcessId = steamProcess?.Id ?? 0;
|
||||
IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
|
||||
// Add a status notification icon in the status area
|
||||
NotifyIcon notify = null;
|
||||
try
|
||||
{
|
||||
notify = new NotifyIcon
|
||||
{
|
||||
Icon = Properties.Resources.HeliosPlus,
|
||||
Text = string.Format(
|
||||
Language.Waiting_for_the_0_to_terminate,
|
||||
steamGameToRun.GameName),
|
||||
Visible = true
|
||||
};
|
||||
Application.DoEvents();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Program/SwitchToSteamGame exception: {ex.Message}: {ex.InnerException}");
|
||||
// ignored
|
||||
}
|
||||
|
||||
// Wait for the game to exit
|
||||
if (steamGameToRun.IsRunning)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (!steamGameToRun.IsRunning)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the status notification icon from the status area
|
||||
// once we've existed the game
|
||||
if (notify != null)
|
||||
{
|
||||
notify.Visible = false;
|
||||
notify.Dispose();
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// If the game is a Uplay Game we check for that
|
||||
/*else if (GameLibrary.Equals(SupportedGameLibrary.Uplay))
|
||||
{
|
||||
// We need to look up details about the game
|
||||
if (!UplayGame.IsInstalled(GameAppId))
|
||||
{
|
||||
return (false, string.Format("The Uplay Game with AppID '{0}' is not installed on this computer.", GameAppId));
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Change back to the original profile if it is different
|
||||
if (!ProfileRepository.IsActiveProfile(rollbackProfile))
|
||||
{
|
||||
if (!ProfileRepository.ApplyProfile(rollbackProfile))
|
||||
{
|
||||
throw new Exception(Language.Cannot_change_active_profile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static bool ChangeToProfile(ProfileItem profile)
|
||||
{
|
||||
// If we're already on the wanted profile then no need to change!
|
||||
if (ProfileRepository.IsActiveProfile(profile))
|
||||
return true;
|
||||
|
||||
var instanceStatus = IPCService.GetInstance().Status;
|
||||
|
||||
try
|
||||
{
|
||||
IPCService.GetInstance().Status = InstanceStatus.Busy;
|
||||
var failed = false;
|
||||
|
||||
if (new ApplyingChangesForm(() =>
|
||||
{
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
if (!(ProfileRepository.ApplyProfile(profile)))
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
}, 3, 30).ShowDialog() !=
|
||||
DialogResult.Cancel)
|
||||
{
|
||||
if (failed)
|
||||
{
|
||||
throw new Exception(Language.Profile_is_invalid_or_not_possible_to_apply);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
IPCService.GetInstance().Status = instanceStatus;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace HeliosPlus.UIForms
|
||||
return;
|
||||
}
|
||||
|
||||
IDictionary<string, Action> actions = dv_profile.Profile.applyProfileActions();
|
||||
/*IDictionary<string, Action> actions = dv_profile.Profile.applyProfileActions();
|
||||
IDictionary<string, string> messages = dv_profile.Profile.applyProfileMsgs();
|
||||
List<string> sequence = dv_profile.Profile.applyProfileSequence();
|
||||
|
||||
@ -68,7 +68,10 @@ namespace HeliosPlus.UIForms
|
||||
Console.WriteLine("Applying profile " + _selectedProfile.Name);
|
||||
}
|
||||
|
||||
Activate();
|
||||
Activate();*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void Exit_Click(object sender, EventArgs e)
|
||||
|
@ -108,6 +108,7 @@
|
||||
this.btn_run.TabIndex = 25;
|
||||
this.btn_run.Text = "&Run";
|
||||
this.btn_run.UseVisualStyleBackColor = false;
|
||||
this.btn_run.Click += new System.EventHandler(this.btn_run_Click);
|
||||
//
|
||||
// btn_edit
|
||||
//
|
||||
|
@ -218,5 +218,14 @@ namespace HeliosPlus.UIForms
|
||||
|
||||
RefreshShortcutLibraryUI();
|
||||
}
|
||||
|
||||
private void btn_run_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_selectedShortcut == null)
|
||||
return;
|
||||
|
||||
// Run the shortcut
|
||||
ShortcutRepository.RunShortcut(_selectedShortcut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user