Fix so application monitoring works

Application monitoring highlighted a failure
in logic, but I fixed it. It now waits for the
timeout period before exiting.
This commit is contained in:
Terry MacDonald 2020-12-11 18:07:17 +13:00
parent 58c8a7f9d2
commit 0f65362860
7 changed files with 110 additions and 101 deletions

View File

@ -73,8 +73,8 @@ namespace DisplayMagician
private string _differentExecutableToMonitor; private string _differentExecutableToMonitor;
private string _executableNameAndPath = ""; private string _executableNameAndPath = "";
private string _executableArguments; private string _executableArguments;
private bool _executableArgumentsRequired; private bool _executableArgumentsRequired = false;
private bool _processNameToMonitorUsesExecutable; private bool _processNameToMonitorUsesExecutable = true;
private uint _gameAppId; private uint _gameAppId;
private string _gameName; private string _gameName;
private SupportedGameLibrary _gameLibrary; private SupportedGameLibrary _gameLibrary;

View File

@ -570,83 +570,82 @@ namespace DisplayMagician
else else
process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath); process = System.Diagnostics.Process.Start(shortcutToUse.ExecutableNameAndPath);
// Create a list of processes to monitor // Figure out what we want to look for
List<Process> processesToMonitor = new List<Process>(); string processNameToLookFor;
// Work out if we are monitoring another process other than the main executable
if (shortcutToUse.ProcessNameToMonitorUsesExecutable) if (shortcutToUse.ProcessNameToMonitorUsesExecutable)
{ {
// If we are monitoring the same executable we started, then lets do that // If we are monitoring the same executable we started, then lets do get that name ready
processesToMonitor.Add(process); processNameToLookFor = System.IO.Path.GetFileNameWithoutExtension(shortcutToUse.ExecutableNameAndPath);
} }
else else
{ {
// Now wait a little while for all the processes we want to monitor to start up // If we are monitoring a different executable, then lets do get that name ready instead
var ticks = 0; processNameToLookFor = System.IO.Path.GetFileNameWithoutExtension(shortcutToUse.DifferentExecutableToMonitor);
while (ticks < shortcutToUse.StartTimeout * 1000) }
// Now look for the thing we're supposed to monitor
// and wait until it starts up
List<Process> processesToMonitor = new List<Process>();
for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
{ {
// Look for the processes with the ProcessName we want (which in Windows is the filename without the extension) // Look for the processes with the ProcessName we sorted out earlier
processesToMonitor = System.Diagnostics.Process.GetProcessesByName(Path.GetFileNameWithoutExtension(shortcutToUse.DifferentExecutableToMonitor)).ToList(); processesToMonitor = Process.GetProcessesByName(processNameToLookFor).ToList();
// If we have found one or more processes then we should be good to go // If we have found one or more processes then we should be good to go
// so let's break // so let's break
if (processesToMonitor.Count > 0) if (processesToMonitor.Count > 0)
{ {
logger.Info($"Found {processesToMonitor.Count} '{processNameToLookFor}' processes have started");
break; break;
} }
// Let's wait a little while if we couldn't find // Let's wait a little while if we couldn't find
// any processes yet // any processes yet
Thread.Sleep(300); Thread.Sleep(500);
ticks += 300;
} }
// make sure we have things to monitor and alert if not
// If we have reached the timeout and we cannot detect any
// of the alernative executables to monitor, then ignore that
// setting, and just monitor the process we just started instead
if (processesToMonitor.Count == 0) if (processesToMonitor.Count == 0)
{ {
processesToMonitor.Add(process); logger.Error($"No '{processNameToLookFor}' processes found before timeout");
}
} }
// Store the process to monitor for later // Store the process to monitor for later
IPCService.GetInstance().HoldProcessId = processesToMonitor.FirstOrDefault()?.Id ?? 0; IPCService.GetInstance().HoldProcessId = processesToMonitor.FirstOrDefault()?.Id ?? 0;
IPCService.GetInstance().Status = InstanceStatus.OnHold; IPCService.GetInstance().Status = InstanceStatus.OnHold;
int substringStart = shortcutToUse.ExecutableNameAndPath.Length - 42; // Add a status notification icon in the status area
if (substringStart < 0) string notificationText = $"DisplayMagician: Running {shortcutToUse.ExecutableNameAndPath}...";
substringStart = 0; if (notificationText.Length >= 64)
notifyIcon.Text = $"DisplayMagician: Running {shortcutToUse.ExecutableNameAndPath.Substring(substringStart)}..."; {
//Application.DoEvents(); string thingToRun = shortcutToUse.ExecutableNameAndPath.Substring(0, 35);
notifyIcon.Text = $"DisplayMagician: Running {thingToRun}...";
}
Application.DoEvents();
// Wait for the monitored process to exit // Wait an extra few seconds to give the application time to settle down
Thread.Sleep(2000);
// if we have things to monitor, then we should start to wait for them
Console.WriteLine($"Waiting for application {processNameToLookFor} to exit.");
logger.Info($"ShortcutRepository/RunShortcut - waiting for application {processNameToLookFor} to exit.");
if (processesToMonitor.Count > 0)
{
logger.Info($"{processesToMonitor.Count} '{processNameToLookFor}' processes are still running");
while (true) while (true)
{ {
int processExitCount = 0; processesToMonitor = Process.GetProcessesByName(processNameToLookFor).ToList();
// Check each process to see if it's exited
foreach (var p in processesToMonitor)
{
try
{
if (p.HasExited)
{
processExitCount++;
}
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"ShortcutRepository/RunShortcut exception 2: {ex.Message}: {ex.StackTrace} - {ex.InnerException}");
logger.Error(ex, $"ShortcutRepository/RunShortcut exception waiting for the monitored process to exit");
processExitCount++;
}
}
// Make sure that all processes have exited // If we have no more processes left then we're done!
// then start the shutdown process if (processesToMonitor.Count == 0)
if (processExitCount == processesToMonitor.Count) {
logger.Info($"No more '{processNameToLookFor}' processes are still running");
break; break;
} }
}
}
Console.WriteLine($"{processNameToLookFor} has exited.");
logger.Info($"ShortcutRepository/RunShortcut - Application {processNameToLookFor} has exited.");
} }
else if (shortcutToUse.Category.Equals(ShortcutCategory.Game)) else if (shortcutToUse.Category.Equals(ShortcutCategory.Game))
@ -675,20 +674,21 @@ namespace DisplayMagician
var steamProcess = Process.Start(address); var steamProcess = Process.Start(address);
// Wait for Steam game to update if needed // Wait for Steam game to update if needed
var ticks = 0; for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
while (ticks < shortcutToUse.StartTimeout * 1000)
{ {
if (steamGameToRun.IsRunning)
{
break;
}
Thread.Sleep(300);
if (!steamGameToRun.IsUpdating) if (!steamGameToRun.IsUpdating)
{ {
ticks += 300; if (steamGameToRun.IsRunning)
{
logger.Info($"Found the '{steamGameToRun.Name}' process has started");
break;
} }
}
// Delay 500ms
Thread.Sleep(500);
} }
// Store the Steam Process ID for later // Store the Steam Process ID for later
@ -749,15 +749,17 @@ namespace DisplayMagician
var uplayProcess = Process.Start(address); var uplayProcess = Process.Start(address);
// Wait for Uplay game to update if needed // Wait for Uplay game to update if needed
var ticks = 0; for (int secs = 0; secs >= (shortcutToUse.StartTimeout * 1000); secs += 500)
while (ticks < shortcutToUse.StartTimeout * 1000)
{ {
if (uplayGameToRun.IsRunning) if (uplayGameToRun.IsRunning)
{ {
logger.Info($"Found the '{uplayGameToRun.Name}' process has started");
break; break;
} }
Thread.Sleep(300); // Delay 500ms
Thread.Sleep(500);
} }
@ -774,6 +776,7 @@ namespace DisplayMagician
// Wait 5 seconds for the game process to spawn // Wait 5 seconds for the game process to spawn
Thread.Sleep(5000); Thread.Sleep(5000);
// Wait for the game to exit // Wait for the game to exit
Console.WriteLine($"Waiting for {uplayGameToRun.Name} to exit."); Console.WriteLine($"Waiting for {uplayGameToRun.Name} to exit.");
logger.Info($"ShortcutRepository/RunShortcut - waiting for Uplay Game {uplayGameToRun.Name} to exit."); logger.Info($"ShortcutRepository/RunShortcut - waiting for Uplay Game {uplayGameToRun.Name} to exit.");

View File

@ -277,7 +277,7 @@ namespace DisplayMagician.UIForms
private void MainForm_Activated(object sender, EventArgs e) private void MainForm_Activated(object sender, EventArgs e)
{ {
EnableShortcutButtonIfProfiles(); //EnableShortcutButtonIfProfiles();
} }
} }
} }

View File

@ -91,7 +91,7 @@ namespace DisplayMagician.UIForms
this.btn_exe_to_start = new System.Windows.Forms.Button(); this.btn_exe_to_start = new System.Windows.Forms.Button();
this.txt_args_executable = new System.Windows.Forms.TextBox(); this.txt_args_executable = new System.Windows.Forms.TextBox();
this.cb_args_executable = new System.Windows.Forms.CheckBox(); this.cb_args_executable = new System.Windows.Forms.CheckBox();
this.btn_app_different_executable = new System.Windows.Forms.Button(); this.btn_choose_alternative_executable = new System.Windows.Forms.Button();
this.txt_alternative_executable = new System.Windows.Forms.TextBox(); this.txt_alternative_executable = new System.Windows.Forms.TextBox();
this.rb_wait_alternative_executable = new System.Windows.Forms.RadioButton(); this.rb_wait_alternative_executable = new System.Windows.Forms.RadioButton();
this.rb_wait_executable = new System.Windows.Forms.RadioButton(); this.rb_wait_executable = new System.Windows.Forms.RadioButton();
@ -808,7 +808,7 @@ namespace DisplayMagician.UIForms
this.p_standalone.Controls.Add(this.btn_exe_to_start); this.p_standalone.Controls.Add(this.btn_exe_to_start);
this.p_standalone.Controls.Add(this.txt_args_executable); this.p_standalone.Controls.Add(this.txt_args_executable);
this.p_standalone.Controls.Add(this.cb_args_executable); this.p_standalone.Controls.Add(this.cb_args_executable);
this.p_standalone.Controls.Add(this.btn_app_different_executable); this.p_standalone.Controls.Add(this.btn_choose_alternative_executable);
this.p_standalone.Controls.Add(this.txt_alternative_executable); this.p_standalone.Controls.Add(this.txt_alternative_executable);
this.p_standalone.Controls.Add(this.rb_wait_alternative_executable); this.p_standalone.Controls.Add(this.rb_wait_alternative_executable);
this.p_standalone.Controls.Add(this.rb_wait_executable); this.p_standalone.Controls.Add(this.rb_wait_executable);
@ -856,17 +856,17 @@ namespace DisplayMagician.UIForms
this.cb_args_executable.CheckedChanged += new System.EventHandler(this.cb_args_executable_CheckedChanged); this.cb_args_executable.CheckedChanged += new System.EventHandler(this.cb_args_executable_CheckedChanged);
this.cb_args_executable.Paint += new System.Windows.Forms.PaintEventHandler(this.checkbox_Paint); this.cb_args_executable.Paint += new System.Windows.Forms.PaintEventHandler(this.checkbox_Paint);
// //
// btn_app_different_executable // btn_choose_alternative_executable
// //
this.btn_app_different_executable.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.btn_choose_alternative_executable.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_app_different_executable.ForeColor = System.Drawing.Color.White; this.btn_choose_alternative_executable.ForeColor = System.Drawing.Color.White;
this.btn_app_different_executable.Location = new System.Drawing.Point(877, 115); this.btn_choose_alternative_executable.Location = new System.Drawing.Point(877, 115);
this.btn_app_different_executable.Name = "btn_app_different_executable"; this.btn_choose_alternative_executable.Name = "btn_choose_alternative_executable";
this.btn_app_different_executable.Size = new System.Drawing.Size(85, 27); this.btn_choose_alternative_executable.Size = new System.Drawing.Size(85, 27);
this.btn_app_different_executable.TabIndex = 9; this.btn_choose_alternative_executable.TabIndex = 9;
this.btn_app_different_executable.Text = "Choose"; this.btn_choose_alternative_executable.Text = "Choose";
this.btn_app_different_executable.UseVisualStyleBackColor = true; this.btn_choose_alternative_executable.UseVisualStyleBackColor = true;
this.btn_app_different_executable.Click += new System.EventHandler(this.btn_app_different_executable_Click); this.btn_choose_alternative_executable.Click += new System.EventHandler(this.btn_choose_alternative_executable_Click);
// //
// txt_alternative_executable // txt_alternative_executable
// //
@ -875,7 +875,7 @@ namespace DisplayMagician.UIForms
this.txt_alternative_executable.Name = "txt_alternative_executable"; this.txt_alternative_executable.Name = "txt_alternative_executable";
this.txt_alternative_executable.Size = new System.Drawing.Size(378, 26); this.txt_alternative_executable.Size = new System.Drawing.Size(378, 26);
this.txt_alternative_executable.TabIndex = 4; this.txt_alternative_executable.TabIndex = 4;
this.txt_alternative_executable.TextChanged += new System.EventHandler(this.txt_different_executable_TextChanged); this.txt_alternative_executable.TextChanged += new System.EventHandler(this.txt_alternative_executable_TextChanged);
// //
// rb_wait_alternative_executable // rb_wait_alternative_executable
// //
@ -887,7 +887,7 @@ namespace DisplayMagician.UIForms
this.rb_wait_alternative_executable.TabIndex = 8; this.rb_wait_alternative_executable.TabIndex = 8;
this.rb_wait_alternative_executable.Text = "Wait until an alternative executable is closed before continuing:"; this.rb_wait_alternative_executable.Text = "Wait until an alternative executable is closed before continuing:";
this.rb_wait_alternative_executable.UseVisualStyleBackColor = true; this.rb_wait_alternative_executable.UseVisualStyleBackColor = true;
this.rb_wait_alternative_executable.CheckedChanged += new System.EventHandler(this.rb_wait_process_CheckedChanged); this.rb_wait_alternative_executable.CheckedChanged += new System.EventHandler(this.rb_wait_alternative_executable_CheckedChanged);
this.rb_wait_alternative_executable.Paint += new System.Windows.Forms.PaintEventHandler(this.radiobutton_Paint); this.rb_wait_alternative_executable.Paint += new System.Windows.Forms.PaintEventHandler(this.radiobutton_Paint);
// //
// rb_wait_executable // rb_wait_executable
@ -1370,7 +1370,7 @@ namespace DisplayMagician.UIForms
private System.Windows.Forms.Panel p_standalone; private System.Windows.Forms.Panel p_standalone;
private System.Windows.Forms.TextBox txt_args_executable; private System.Windows.Forms.TextBox txt_args_executable;
private System.Windows.Forms.CheckBox cb_args_executable; private System.Windows.Forms.CheckBox cb_args_executable;
private System.Windows.Forms.Button btn_app_different_executable; private System.Windows.Forms.Button btn_choose_alternative_executable;
private System.Windows.Forms.TextBox txt_alternative_executable; private System.Windows.Forms.TextBox txt_alternative_executable;
private System.Windows.Forms.RadioButton rb_wait_alternative_executable; private System.Windows.Forms.RadioButton rb_wait_alternative_executable;
private System.Windows.Forms.RadioButton rb_wait_executable; private System.Windows.Forms.RadioButton rb_wait_executable;

View File

@ -63,7 +63,7 @@ namespace DisplayMagician.UIForms
}*/ }*/
} }
public string ProcessNameToMonitor /* public string ProcessNameToMonitor
{ {
get get
{ {
@ -79,11 +79,11 @@ namespace DisplayMagician.UIForms
{ {
// We we're setting this entry, then we want to set it to a particular entry // We we're setting this entry, then we want to set it to a particular entry
txt_alternative_executable.Text = value; txt_alternative_executable.Text = value;
rb_wait_executable.Checked = true; //rb_wait_executable.Checked = true;
} }
} }
*/
public string ExecutableNameAndPath /* public string ExecutableNameAndPath
{ {
get => rb_switch_display_temp.Checked && rb_launcher.Checked ? txt_executable.Text : string.Empty; get => rb_switch_display_temp.Checked && rb_launcher.Checked ? txt_executable.Text : string.Empty;
set set
@ -96,8 +96,8 @@ namespace DisplayMagician.UIForms
} }
} }
} }
*/
public uint ExecutableTimeout /* public uint ExecutableTimeout
{ {
get get
{ {
@ -147,7 +147,7 @@ namespace DisplayMagician.UIForms
txt_game_name.Text = value; txt_game_name.Text = value;
} }
} }
*/
public ShortcutItem Shortcut public ShortcutItem Shortcut
{ {
get => _shortcutToEdit; get => _shortcutToEdit;
@ -549,7 +549,7 @@ namespace DisplayMagician.UIForms
this.Close(); this.Close();
} }
private void txt_different_executable_TextChanged(object sender, EventArgs e) private void txt_alternative_executable_TextChanged(object sender, EventArgs e)
{ {
if (_loadedShortcut) if (_loadedShortcut)
_isUnsaved = true; _isUnsaved = true;
@ -951,14 +951,18 @@ namespace DisplayMagician.UIForms
{ {
cb_args_executable.Checked = true; cb_args_executable.Checked = true;
} }
else
{
cb_args_executable.Checked = false;
}
if (_shortcutToEdit.ProcessNameToMonitorUsesExecutable) if (_shortcutToEdit.ProcessNameToMonitorUsesExecutable)
{ {
rb_wait_executable.Checked = true; rb_wait_executable.Checked = true;
rb_wait_alternative_executable.Checked = false; //rb_wait_alternative_executable.Checked = false;
} }
else else
{ {
rb_wait_executable.Checked = false; //rb_wait_executable.Checked = false;
rb_wait_alternative_executable.Checked = true; rb_wait_alternative_executable.Checked = true;
} }
txt_alternative_executable.Text = _shortcutToEdit.DifferentExecutableToMonitor; txt_alternative_executable.Text = _shortcutToEdit.DifferentExecutableToMonitor;
@ -1022,7 +1026,7 @@ namespace DisplayMagician.UIForms
} }
private void rb_wait_process_CheckedChanged(object sender, EventArgs e) private void rb_wait_alternative_executable_CheckedChanged(object sender, EventArgs e)
{ {
if (rb_wait_alternative_executable.Checked) if (rb_wait_alternative_executable.Checked)
{ {
@ -1030,6 +1034,7 @@ namespace DisplayMagician.UIForms
_isUnsaved = true; _isUnsaved = true;
rb_wait_executable.Checked = false; rb_wait_executable.Checked = false;
txt_alternative_executable.Enabled = true; txt_alternative_executable.Enabled = true;
btn_choose_alternative_executable.Enabled = true;
} }
} }
@ -1041,11 +1046,12 @@ namespace DisplayMagician.UIForms
_isUnsaved = true; _isUnsaved = true;
rb_wait_alternative_executable.Checked = false; rb_wait_alternative_executable.Checked = false;
txt_alternative_executable.Enabled = false; txt_alternative_executable.Enabled = false;
btn_choose_alternative_executable.Enabled = false;
} }
} }
private void btn_app_different_executable_Click(object sender, EventArgs e) private void btn_choose_alternative_executable_Click(object sender, EventArgs e)
{ {
if (dialog_open.ShowDialog(this) == DialogResult.OK) if (dialog_open.ShowDialog(this) == DialogResult.OK)
{ {

View File

@ -270,7 +270,7 @@
this.ShowIcon = false; this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "DisplayMagician - Setup Game Shortcuts"; this.Text = "DisplayMagician - Setup Game Shortcuts";
this.Activated += new System.EventHandler(this.ShortcutLibraryForm_Activated); //this.Activated += new System.EventHandler(this.ShortcutLibraryForm_Activated);
this.Load += new System.EventHandler(this.ShortcutLibraryForm_Load); this.Load += new System.EventHandler(this.ShortcutLibraryForm_Load);
this.cms_shortcuts.ResumeLayout(false); this.cms_shortcuts.ResumeLayout(false);
this.ResumeLayout(false); this.ResumeLayout(false);

View File

@ -279,7 +279,7 @@ namespace DisplayMagician.UIForms
private void ShortcutLibraryForm_Activated(object sender, EventArgs e) private void ShortcutLibraryForm_Activated(object sender, EventArgs e)
{ {
RemoveWarningIfShortcuts(); //RemoveWarningIfShortcuts();
} }
private void tsmi_save_to_desktop_Click(object sender, EventArgs e) private void tsmi_save_to_desktop_Click(object sender, EventArgs e)