mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
[WIP] Partially working process launching
Still need to iron out all the bugs and get it working with launchers etc.
This commit is contained in:
parent
852d42ed6f
commit
0d96a9287d
@ -107,8 +107,11 @@ namespace DisplayMagician.GameLibraries
|
|||||||
{
|
{
|
||||||
//if (gameProcess.MainModule.FileName.StartsWith(_steamGameExePath))
|
//if (gameProcess.MainModule.FileName.StartsWith(_steamGameExePath))
|
||||||
// numGameProcesses++;
|
// numGameProcesses++;
|
||||||
if (gameProcess.ProcessName.Equals(_steamGameProcessName))
|
if (!gameProcess.HasExited)
|
||||||
|
{
|
||||||
numGameProcesses++;
|
numGameProcesses++;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -823,6 +823,9 @@ namespace DisplayMagician.GameLibraries
|
|||||||
}
|
}
|
||||||
//Process gameProcess = Process.Start(address);
|
//Process gameProcess = Process.Start(address);
|
||||||
List<Process> gameProcesses = ProcessUtils.StartProcess(address,null,processPriority);
|
List<Process> gameProcesses = ProcessUtils.StartProcess(address,null,processPriority);
|
||||||
|
|
||||||
|
// Wait 1 second then see if we need to find the child processes.
|
||||||
|
|
||||||
return gameProcesses;
|
return gameProcesses;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -56,16 +56,21 @@ namespace DisplayMagician.Processes
|
|||||||
|
|
||||||
public static List<Process> StartProcess(string executable, string arguments, ProcessPriority processPriority, int startTimeout = 1)
|
public static List<Process> StartProcess(string executable, string arguments, ProcessPriority processPriority, int startTimeout = 1)
|
||||||
{
|
{
|
||||||
List<Process> runningProcesses = new List<Process>();
|
List<Process> startedProcesses = new List<Process>();
|
||||||
Process process = null;
|
List<Process> returnedProcesses;
|
||||||
bool usingChildProcess = false;
|
//bool usingChildProcess = false;
|
||||||
|
|
||||||
if (TryExecute_AutoImpersonate(executable, arguments, out process))
|
if (TryExecute_AutoImpersonate(executable, arguments, out returnedProcesses))
|
||||||
{
|
{
|
||||||
logger.Trace($"ProcessUtils/StartProcess: {executable} {arguments} has successfully been started (ID: {process.Id})");
|
logger.Trace($"ProcessUtils/StartProcess: {executable} {arguments} has successfully been started");
|
||||||
runningProcesses.Add(process);
|
|
||||||
}
|
}
|
||||||
return runningProcesses;
|
else
|
||||||
|
{
|
||||||
|
logger.Trace($"ProcessUtils/StartProcess: {executable} {arguments} was unable to be started");
|
||||||
|
}
|
||||||
|
startedProcesses = returnedProcesses;
|
||||||
|
|
||||||
|
return startedProcesses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Process> GetChildProcesses(Process process)
|
public static List<Process> GetChildProcesses(Process process)
|
||||||
@ -252,7 +257,7 @@ namespace DisplayMagician.Processes
|
|||||||
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
||||||
public static bool TryExecute(string executable, string arguments, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
public static bool TryExecute(string executable, string arguments, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
||||||
{
|
{
|
||||||
Process unused;
|
List<Process> unused;
|
||||||
return TryExecute(executable, arguments, out unused, priorityClass, maxWaitMs);
|
return TryExecute(executable, arguments, out unused, priorityClass, maxWaitMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,11 +271,19 @@ namespace DisplayMagician.Processes
|
|||||||
/// <param name="priorityClass">Process priority</param>
|
/// <param name="priorityClass">Process priority</param>
|
||||||
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
||||||
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
||||||
public static bool TryExecute_AutoImpersonate(string executable, string arguments, out Process process, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
public static bool TryExecute_AutoImpersonate(string executable, string arguments, out List<Process> processes, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
||||||
{
|
{
|
||||||
return IsImpersonated ?
|
bool result = false;
|
||||||
TryExecute_Impersonated(executable, arguments, out process, priorityClass, maxWaitMs) :
|
if (IsImpersonated)
|
||||||
TryExecute(executable, arguments, out process, priorityClass, maxWaitMs);
|
{
|
||||||
|
result = TryExecute_Impersonated(executable, arguments, out processes, priorityClass, maxWaitMs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = TryExecute(executable, arguments, out processes, priorityClass, maxWaitMs);
|
||||||
|
}
|
||||||
|
//process = processReturned;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -282,16 +295,16 @@ namespace DisplayMagician.Processes
|
|||||||
/// <param name="priorityClass">Process priority</param>
|
/// <param name="priorityClass">Process priority</param>
|
||||||
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
||||||
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
||||||
public static bool TryExecute_Impersonated(string executable, string arguments, out Process process, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
public static bool TryExecute_Impersonated(string executable, string arguments, out List<Process> processes, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
||||||
{
|
{
|
||||||
IntPtr userToken;
|
IntPtr userToken;
|
||||||
process = null;
|
processes = new List<Process>();
|
||||||
if (!ImpersonationHelper.GetTokenByProcess(out userToken, true))
|
if (!ImpersonationHelper.GetTokenByProcess(out userToken, true))
|
||||||
return false;
|
return false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//return TryExecute_Impersonated(executable, arguments, userToken, false, out unused, priorityClass, maxWaitMs);
|
//return TryExecute_Impersonated(executable, arguments, userToken, false, out unused, priorityClass, maxWaitMs);
|
||||||
return TryExecute_Impersonated(executable, arguments, userToken, out process, priorityClass, maxWaitMs);
|
return TryExecute_Impersonated(executable, arguments, userToken, out processes, priorityClass, maxWaitMs);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -309,7 +322,7 @@ namespace DisplayMagician.Processes
|
|||||||
/// <param name="priorityClass">Process priority</param>
|
/// <param name="priorityClass">Process priority</param>
|
||||||
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool TryExecuteReadString(string executable, string arguments, out Process process, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
public static bool TryExecuteReadString(string executable, string arguments, out List<Process> process, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
||||||
{
|
{
|
||||||
return TryExecute(executable, arguments, out process, priorityClass, maxWaitMs);
|
return TryExecute(executable, arguments, out process, priorityClass, maxWaitMs);
|
||||||
}
|
}
|
||||||
@ -324,11 +337,11 @@ namespace DisplayMagician.Processes
|
|||||||
/// <param name="priorityClass">Process priority</param>
|
/// <param name="priorityClass">Process priority</param>
|
||||||
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool TryExecuteReadString_AutoImpersonate(string executable, string arguments, out Process process, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
public static bool TryExecuteReadString_AutoImpersonate(string executable, string arguments, out List<Process> processes, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
||||||
{
|
{
|
||||||
return IsImpersonated ?
|
return IsImpersonated ?
|
||||||
TryExecuteReadString_Impersonated(executable, arguments, out process, priorityClass, maxWaitMs) :
|
TryExecuteReadString_Impersonated(executable, arguments, out processes, priorityClass, maxWaitMs) :
|
||||||
TryExecuteReadString(executable, arguments, out process, priorityClass, maxWaitMs);
|
TryExecuteReadString(executable, arguments, out processes, priorityClass, maxWaitMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -342,17 +355,17 @@ namespace DisplayMagician.Processes
|
|||||||
/// <param name="priorityClass">Process priority</param>
|
/// <param name="priorityClass">Process priority</param>
|
||||||
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
||||||
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
||||||
public static bool TryExecuteReadString_Impersonated(string executable, string arguments, out Process process, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = INFINITE)
|
public static bool TryExecuteReadString_Impersonated(string executable, string arguments, out List<Process> processes, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = INFINITE)
|
||||||
{
|
{
|
||||||
IntPtr userToken;
|
IntPtr userToken;
|
||||||
if (!ImpersonationHelper.GetTokenByProcess(out userToken, true))
|
if (!ImpersonationHelper.GetTokenByProcess(out userToken, true))
|
||||||
{
|
{
|
||||||
process = null;
|
processes = new List<Process>();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return TryExecute_Impersonated(executable, arguments, userToken, out process, priorityClass, maxWaitMs);
|
return TryExecute_Impersonated(executable, arguments, userToken, out processes, priorityClass, maxWaitMs);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -426,10 +439,10 @@ namespace DisplayMagician.Processes
|
|||||||
/// <param name="priorityClass">Process priority</param>
|
/// <param name="priorityClass">Process priority</param>
|
||||||
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static bool TryExecute(string executable, string arguments, out Process process, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
private static bool TryExecute(string executable, string arguments, out List<Process> startedProcesses, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
||||||
{
|
{
|
||||||
//StringBuilder outputBuilder = new StringBuilder();
|
//StringBuilder outputBuilder = new StringBuilder();
|
||||||
|
startedProcesses = new List<Process>();
|
||||||
bool _isFile = false;
|
bool _isFile = false;
|
||||||
bool _isExe = false;
|
bool _isExe = false;
|
||||||
if (File.Exists(executable))
|
if (File.Exists(executable))
|
||||||
@ -469,44 +482,102 @@ namespace DisplayMagician.Processes
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
using (Process processCreated = new Process { StartInfo = psi })
|
Process processCreated = new Process { StartInfo = psi };
|
||||||
|
|
||||||
|
/*if (redirectInputOutput)
|
||||||
{
|
{
|
||||||
/*if (redirectInputOutput)
|
// Set UTF-8 encoding for standard output.
|
||||||
{
|
process.StartInfo.StandardOutputEncoding = CONSOLE_ENCODING;
|
||||||
// Set UTF-8 encoding for standard output.
|
// Enable raising events because Process does not raise events by default.
|
||||||
process.StartInfo.StandardOutputEncoding = CONSOLE_ENCODING;
|
process.EnableRaisingEvents = true;
|
||||||
// Enable raising events because Process does not raise events by default.
|
// Attach the event handler for OutputDataReceived before starting the process.
|
||||||
process.EnableRaisingEvents = true;
|
process.OutputDataReceived += (sender, e) => outputBuilder.Append(e.Data);
|
||||||
// Attach the event handler for OutputDataReceived before starting the process.
|
}*/
|
||||||
process.OutputDataReceived += (sender, e) => outputBuilder.Append(e.Data);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
processCreated.Start();
|
processCreated.Start();
|
||||||
|
}
|
||||||
/*if (redirectInputOutput)
|
catch (ObjectDisposedException ex)
|
||||||
process.BeginOutputReadLine();*/
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. The process object has already been disposed.");
|
||||||
if (processCreated.WaitForExit(maxWaitMs))
|
return false;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ex)
|
||||||
|
{
|
||||||
|
if (processCreated.StartInfo.UseShellExecute && (processCreated.StartInfo.RedirectStandardInput || processCreated.StartInfo.RedirectStandardOutput || processCreated.StartInfo.RedirectStandardError))
|
||||||
{
|
{
|
||||||
//result = RemoveEncodingPreamble(outputBuilder.ToString());
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. The UseShellExecute member of the StartInfo property is true while RedirectStandardInput, RedirectStandardOutput, or RedirectStandardError is true.");
|
||||||
if (!processCreated.HasExited)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. No file name was specified in the Process component's StartInfo.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Win32Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. There was an error in opening the associated file.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (PlatformNotSupportedException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. Method not supported on operating systems without shell support such as Nano Server (.NET Core only).");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. Not sure what specific exception it is.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (redirectInputOutput)
|
||||||
|
process.BeginOutputReadLine();*/
|
||||||
|
|
||||||
|
//result = RemoveEncodingPreamble(outputBuilder.ToString());
|
||||||
|
if (processCreated != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
processCreated.WaitForExit(1000);
|
||||||
|
|
||||||
|
if (processCreated.HasExited)
|
||||||
{
|
{
|
||||||
|
// If the process has exited, then it's likely to be a launcher, so we try to find the children processes
|
||||||
|
List<Process> childProcesses = GetChildProcesses(processCreated);
|
||||||
|
startedProcesses.AddRange(childProcesses);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we're here then the process was created and hasn't exited!
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
processCreated.PriorityClass = priorityClass;
|
if (processCreated.PriorityClass != priorityClass)
|
||||||
|
{
|
||||||
|
processCreated.PriorityClass = priorityClass;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to set the Priority Class to {priorityClass.ToString("G")} for {executable}.");
|
logger.Warn(ex, $"ProcessUtils/StartProcess: Exception while trying to set the Priority Class to {priorityClass.ToString("G")} for {executable}.");
|
||||||
}
|
}
|
||||||
process = processCreated;
|
startedProcesses.Add(processCreated);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Oops- the process didn't work. Let's skip this one
|
||||||
|
//process = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//process = processCreated;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
process = null;
|
|
||||||
|
//process = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,45 +638,105 @@ namespace DisplayMagician.Processes
|
|||||||
/// <param name="priorityClass">Process priority</param>
|
/// <param name="priorityClass">Process priority</param>
|
||||||
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
/// <param name="maxWaitMs">Maximum time to wait for completion</param>
|
||||||
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
/// <returns><c>true</c> if process was executed and finished correctly</returns>
|
||||||
private static bool TryExecute_Impersonated(string executable, string arguments, IntPtr token, out Process process, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
private static bool TryExecute_Impersonated(string executable, string arguments, IntPtr token, out List<Process> startedProcesses, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = 1000)
|
||||||
{
|
{
|
||||||
// TODO: code is 99% redundant to TryExecute, refactor Process/ImpersonationProcess and Start/StartAsUser!
|
// TODO: code is 99% redundant to TryExecute, refactor Process/ImpersonationProcess and Start/StartAsUser!
|
||||||
StringBuilder outputBuilder = new StringBuilder();
|
StringBuilder outputBuilder = new StringBuilder();
|
||||||
using (ImpersonationProcess processCreated = new ImpersonationProcess { StartInfo = new ProcessStartInfo(executable, arguments) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = false} })
|
startedProcesses = new List<Process>();
|
||||||
|
ImpersonationProcess processCreated = new ImpersonationProcess { StartInfo = new ProcessStartInfo(executable, arguments) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = false } };
|
||||||
|
/*if (redirectInputOutput)
|
||||||
|
{
|
||||||
|
// Set UTF-8 encoding for standard output.
|
||||||
|
process.StartInfo.StandardOutputEncoding = CONSOLE_ENCODING;
|
||||||
|
// Enable raising events because Process does not raise events by default.
|
||||||
|
process.EnableRaisingEvents = true;
|
||||||
|
// Attach the event handler for OutputDataReceived before starting the process.
|
||||||
|
process.OutputDataReceived += (sender, e) => outputBuilder.Append(e.Data);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
/*if (redirectInputOutput)
|
|
||||||
{
|
|
||||||
// Set UTF-8 encoding for standard output.
|
|
||||||
process.StartInfo.StandardOutputEncoding = CONSOLE_ENCODING;
|
|
||||||
// Enable raising events because Process does not raise events by default.
|
|
||||||
process.EnableRaisingEvents = true;
|
|
||||||
// Attach the event handler for OutputDataReceived before starting the process.
|
|
||||||
process.OutputDataReceived += (sender, e) => outputBuilder.Append(e.Data);
|
|
||||||
}*/
|
|
||||||
processCreated.StartAsUser(token);
|
processCreated.StartAsUser(token);
|
||||||
|
}
|
||||||
/*if (redirectInputOutput)
|
catch (ObjectDisposedException ex)
|
||||||
process.BeginOutputReadLine();*/
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. The process object has already been disposed.");
|
||||||
if (processCreated.WaitForExit(maxWaitMs))
|
return false;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ex)
|
||||||
|
{
|
||||||
|
if (processCreated.StartInfo.UseShellExecute && (processCreated.StartInfo.RedirectStandardInput || processCreated.StartInfo.RedirectStandardOutput || processCreated.StartInfo.RedirectStandardError))
|
||||||
{
|
{
|
||||||
//result = RemoveEncodingPreamble(outputBuilder.ToString());
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. The UseShellExecute member of the StartInfo property is true while RedirectStandardInput, RedirectStandardOutput, or RedirectStandardError is true.");
|
||||||
if (!processCreated.HasExited)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. No file name was specified in the Process component's StartInfo.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Win32Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. There was an error in opening the associated file.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (PlatformNotSupportedException ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. Method not supported on operating systems without shell support such as Nano Server (.NET Core only).");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Error(ex, $"ProcessUtils/TryExecute: Exception while trying to start {executable}. Not sure what specific exception it is.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (redirectInputOutput)
|
||||||
|
process.BeginOutputReadLine();*/
|
||||||
|
|
||||||
|
if (processCreated != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
processCreated.WaitForExit(1000);
|
||||||
|
|
||||||
|
if (processCreated.HasExited)
|
||||||
{
|
{
|
||||||
|
// If the process has exited, then it's likely to be a launcher, so we try to find the children processes
|
||||||
|
List<Process> childProcesses = GetChildProcesses(processCreated);
|
||||||
|
startedProcesses.AddRange(childProcesses);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we're here then the process was created and hasn't exited!
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
processCreated.PriorityClass = priorityClass;
|
if (processCreated.PriorityClass != priorityClass)
|
||||||
|
{
|
||||||
|
processCreated.PriorityClass = priorityClass;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.Error(ex, $"ProcessUtils/TryExecute_Impersonated: Exception while trying to set the Priority Class to {priorityClass.ToString("G")} for {executable}.");
|
logger.Warn(ex, $"ProcessUtils/StartProcess: Exception while trying to set the Priority Class to {priorityClass.ToString("G")} for {executable}.");
|
||||||
}
|
}
|
||||||
process = processCreated;
|
startedProcesses.Add(processCreated);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Oops- the process didn't work. Let's skip this one
|
||||||
|
//process = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//process = processCreated;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
process = null;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,6 +752,33 @@ namespace DisplayMagician.Processes
|
|||||||
return rawString;
|
return rawString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ProcessPriorityClass TranslatePriorityToClass(ProcessPriority processPriorityClass)
|
||||||
|
{
|
||||||
|
ProcessPriorityClass wantedPriorityClass = ProcessPriorityClass.Normal;
|
||||||
|
switch (processPriorityClass)
|
||||||
|
{
|
||||||
|
case ProcessPriority.High:
|
||||||
|
wantedPriorityClass = ProcessPriorityClass.High;
|
||||||
|
break;
|
||||||
|
case ProcessPriority.AboveNormal:
|
||||||
|
wantedPriorityClass = ProcessPriorityClass.AboveNormal;
|
||||||
|
break;
|
||||||
|
case ProcessPriority.Normal:
|
||||||
|
wantedPriorityClass = ProcessPriorityClass.Normal;
|
||||||
|
break;
|
||||||
|
case ProcessPriority.BelowNormal:
|
||||||
|
wantedPriorityClass = ProcessPriorityClass.BelowNormal;
|
||||||
|
break;
|
||||||
|
case ProcessPriority.Idle:
|
||||||
|
wantedPriorityClass = ProcessPriorityClass.Idle;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wantedPriorityClass = ProcessPriorityClass.Normal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return wantedPriorityClass;
|
||||||
|
}
|
||||||
|
|
||||||
public static PROCESS_CREATION_FLAGS TranslatePriorityClassToFlags(ProcessPriorityClass processPriorityClass)
|
public static PROCESS_CREATION_FLAGS TranslatePriorityClassToFlags(ProcessPriorityClass processPriorityClass)
|
||||||
{
|
{
|
||||||
PROCESS_CREATION_FLAGS wantedPriorityClass = PROCESS_CREATION_FLAGS.NORMAL_PRIORITY_CLASS;
|
PROCESS_CREATION_FLAGS wantedPriorityClass = PROCESS_CREATION_FLAGS.NORMAL_PRIORITY_CLASS;
|
||||||
|
@ -26,8 +26,8 @@ using System.Resources;
|
|||||||
[assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
|
[assembly: Guid("e4ceaf5e-ad01-4695-b179-31168eb74c48")]
|
||||||
|
|
||||||
// Version information
|
// Version information
|
||||||
[assembly: AssemblyVersion("2.1.0.287")]
|
[assembly: AssemblyVersion("2.1.0.308")]
|
||||||
[assembly: AssemblyFileVersion("2.1.0.287")]
|
[assembly: AssemblyFileVersion("2.1.0.308")]
|
||||||
[assembly: NeutralResourcesLanguageAttribute( "en" )]
|
[assembly: NeutralResourcesLanguageAttribute( "en" )]
|
||||||
[assembly: CLSCompliant(true)]
|
[assembly: CLSCompliant(true)]
|
||||||
|
|
||||||
|
@ -1276,6 +1276,15 @@ namespace DisplayMagician
|
|||||||
// Delay 500ms
|
// Delay 500ms
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
|
|
||||||
|
if (gameProcesses.Count == 0)
|
||||||
|
{
|
||||||
|
// If there are no children found, then try to find all the running programs with the same names
|
||||||
|
// (Some games relaunch themselves!)
|
||||||
|
List<Process> sameNamedProcesses = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(gameToRun.Executable)).ToList();
|
||||||
|
gameProcesses.AddRange(sameNamedProcesses);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Wait for GameLibrary to start
|
// Wait for GameLibrary to start
|
||||||
for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
||||||
{
|
{
|
||||||
@ -1659,12 +1668,14 @@ namespace DisplayMagician
|
|||||||
|
|
||||||
// Now we know the game library app is running then
|
// Now we know the game library app is running then
|
||||||
// we wait until the game has started running (*allows for updates to occur)
|
// we wait until the game has started running (*allows for updates to occur)
|
||||||
|
bool gameRunning = false;
|
||||||
for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
for (int secs = 0; secs <= (shortcutToUse.StartTimeout * 1000); secs += 500)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (gameToRun.IsRunning)
|
if (gameToRun.IsRunning)
|
||||||
{
|
{
|
||||||
// The game is running! So now we continue processing
|
// The game is running! So now we continue processing
|
||||||
|
gameRunning = true;
|
||||||
logger.Debug($"ShortcutRepository/RunShortcut: Found the '{gameToRun.Name}' process has started");
|
logger.Debug($"ShortcutRepository/RunShortcut: Found the '{gameToRun.Name}' process has started");
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -1683,13 +1694,14 @@ namespace DisplayMagician
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Delay 500ms
|
// Delay 500ms
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the game still isn't running then there is an issue so tell the user and revert things back
|
// If the game still isn't running then there is an issue so tell the user and revert things back
|
||||||
if (!gameToRun.IsRunning)
|
if (!gameRunning)
|
||||||
{
|
{
|
||||||
logger.Error($"ShortcutRepository/RunShortcut: The Game {gameToRun.Name} didn't start for some reason (or the game uses a starter exe that launches the game itself)! so reverting changes back if needed...");
|
logger.Error($"ShortcutRepository/RunShortcut: The Game {gameToRun.Name} didn't start for some reason (or the game uses a starter exe that launches the game itself)! so reverting changes back if needed...");
|
||||||
logger.Warn($"ShortcutRepository/RunShortcut: We were monitoring {gameToRun.ExePath}. You may need to manually add an alternative game executable to monitor - please run the game manually and check if another executable in {Path.GetDirectoryName(gameToRun.ExePath)} is run, and then monitor that instead.");
|
logger.Warn($"ShortcutRepository/RunShortcut: We were monitoring {gameToRun.ExePath}. You may need to manually add an alternative game executable to monitor - please run the game manually and check if another executable in {Path.GetDirectoryName(gameToRun.ExePath)} is run, and then monitor that instead.");
|
||||||
|
Loading…
Reference in New Issue
Block a user