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 _executableNameAndPath = "";
private string _executableArguments;
private bool _executableArgumentsRequired;
private bool _processNameToMonitorUsesExecutable;
private bool _executableArgumentsRequired = false;
private bool _processNameToMonitorUsesExecutable = true;
private uint _gameAppId;
private string _gameName;
private SupportedGameLibrary _gameLibrary;

View File

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

View File

@ -91,7 +91,7 @@ namespace DisplayMagician.UIForms
this.btn_exe_to_start = new System.Windows.Forms.Button();
this.txt_args_executable = new System.Windows.Forms.TextBox();
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.rb_wait_alternative_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.txt_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.rb_wait_alternative_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.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_app_different_executable.ForeColor = System.Drawing.Color.White;
this.btn_app_different_executable.Location = new System.Drawing.Point(877, 115);
this.btn_app_different_executable.Name = "btn_app_different_executable";
this.btn_app_different_executable.Size = new System.Drawing.Size(85, 27);
this.btn_app_different_executable.TabIndex = 9;
this.btn_app_different_executable.Text = "Choose";
this.btn_app_different_executable.UseVisualStyleBackColor = true;
this.btn_app_different_executable.Click += new System.EventHandler(this.btn_app_different_executable_Click);
this.btn_choose_alternative_executable.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btn_choose_alternative_executable.ForeColor = System.Drawing.Color.White;
this.btn_choose_alternative_executable.Location = new System.Drawing.Point(877, 115);
this.btn_choose_alternative_executable.Name = "btn_choose_alternative_executable";
this.btn_choose_alternative_executable.Size = new System.Drawing.Size(85, 27);
this.btn_choose_alternative_executable.TabIndex = 9;
this.btn_choose_alternative_executable.Text = "Choose";
this.btn_choose_alternative_executable.UseVisualStyleBackColor = true;
this.btn_choose_alternative_executable.Click += new System.EventHandler(this.btn_choose_alternative_executable_Click);
//
// txt_alternative_executable
//
@ -875,7 +875,7 @@ namespace DisplayMagician.UIForms
this.txt_alternative_executable.Name = "txt_alternative_executable";
this.txt_alternative_executable.Size = new System.Drawing.Size(378, 26);
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
//
@ -887,7 +887,7 @@ namespace DisplayMagician.UIForms
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.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);
//
// rb_wait_executable
@ -1370,7 +1370,7 @@ namespace DisplayMagician.UIForms
private System.Windows.Forms.Panel p_standalone;
private System.Windows.Forms.TextBox txt_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.RadioButton rb_wait_alternative_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
{
@ -79,11 +79,11 @@ namespace DisplayMagician.UIForms
{
// We we're setting this entry, then we want to set it to a particular entry
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;
set
@ -96,8 +96,8 @@ namespace DisplayMagician.UIForms
}
}
}
public uint ExecutableTimeout
*/
/* public uint ExecutableTimeout
{
get
{
@ -147,7 +147,7 @@ namespace DisplayMagician.UIForms
txt_game_name.Text = value;
}
}
*/
public ShortcutItem Shortcut
{
get => _shortcutToEdit;
@ -549,7 +549,7 @@ namespace DisplayMagician.UIForms
this.Close();
}
private void txt_different_executable_TextChanged(object sender, EventArgs e)
private void txt_alternative_executable_TextChanged(object sender, EventArgs e)
{
if (_loadedShortcut)
_isUnsaved = true;
@ -951,14 +951,18 @@ namespace DisplayMagician.UIForms
{
cb_args_executable.Checked = true;
}
else
{
cb_args_executable.Checked = false;
}
if (_shortcutToEdit.ProcessNameToMonitorUsesExecutable)
{
rb_wait_executable.Checked = true;
rb_wait_alternative_executable.Checked = false;
//rb_wait_alternative_executable.Checked = false;
}
else
{
rb_wait_executable.Checked = false;
//rb_wait_executable.Checked = false;
rb_wait_alternative_executable.Checked = true;
}
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)
{
@ -1030,6 +1034,7 @@ namespace DisplayMagician.UIForms
_isUnsaved = true;
rb_wait_executable.Checked = false;
txt_alternative_executable.Enabled = true;
btn_choose_alternative_executable.Enabled = true;
}
}
@ -1041,11 +1046,12 @@ namespace DisplayMagician.UIForms
_isUnsaved = true;
rb_wait_alternative_executable.Checked = 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)
{

View File

@ -270,7 +270,7 @@
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
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.cms_shortcuts.ResumeLayout(false);
this.ResumeLayout(false);

View File

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