mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
feat: continuously check for game window, don't use WaitForInputIdle(), throw exception if timeout
This commit is contained in:
parent
c3e16ad92c
commit
bd7f3f6033
2 changed files with 35 additions and 16 deletions
|
|
@ -604,9 +604,13 @@ namespace Dalamud.Injector
|
|||
Log.Error("[HOOKS] RewriteRemoteEntryPointW failed");
|
||||
throw new Exception("RewriteRemoteEntryPointW failed");
|
||||
}
|
||||
|
||||
Log.Verbose("RewriteRemoteEntryPointW called!");
|
||||
}
|
||||
});
|
||||
|
||||
Log.Verbose("Game process started with PID {0}", process.Id);
|
||||
|
||||
if (!withoutDalamud && mode == "inject")
|
||||
{
|
||||
var startInfo = AdjustStartInfo(dalamudStartInfo, gamePath);
|
||||
|
|
|
|||
|
|
@ -24,13 +24,14 @@ namespace Dalamud.Injector
|
|||
/// <param name="arguments">Arguments to pass to the executable file.</param>
|
||||
/// <param name="dontFixAcl">Don't actually fix the ACL.</param>
|
||||
/// <param name="beforeResume">Action to execute before the process is started.</param>
|
||||
/// <param name="waitForGameWindow">Wait for the game window to be ready before proceeding.</param>
|
||||
/// <returns>The started process.</returns>
|
||||
/// <exception cref="Win32Exception">Thrown when a win32 error occurs.</exception>
|
||||
/// <exception cref="GameExitedException">Thrown when the process did not start correctly.</exception>
|
||||
public static Process LaunchGame(string workingDir, string exePath, string arguments, bool dontFixAcl, Action<Process> beforeResume)
|
||||
/// <exception cref="GameStartException">Thrown when the process did not start correctly.</exception>
|
||||
public static Process LaunchGame(string workingDir, string exePath, string arguments, bool dontFixAcl, Action<Process> beforeResume, bool waitForGameWindow = true)
|
||||
{
|
||||
Process process = null;
|
||||
|
||||
|
||||
var psecDesc = IntPtr.Zero;
|
||||
if (!dontFixAcl)
|
||||
{
|
||||
|
|
@ -121,19 +122,32 @@ namespace Dalamud.Injector
|
|||
PInvoke.ResumeThread(lpProcessInformation.hThread);
|
||||
|
||||
// Ensure that the game main window is prepared
|
||||
try
|
||||
if (waitForGameWindow)
|
||||
{
|
||||
do
|
||||
try
|
||||
{
|
||||
process.WaitForInputIdle();
|
||||
var tries = 0;
|
||||
const int maxTries = 120;
|
||||
const int timeout = 50;
|
||||
|
||||
Thread.Sleep(100);
|
||||
do
|
||||
{
|
||||
Thread.Sleep(timeout);
|
||||
|
||||
if (process.HasExited)
|
||||
throw new GameStartException();
|
||||
|
||||
if (tries > maxTries)
|
||||
throw new GameStartException($"Couldn't find game window after {maxTries * timeout}ms");
|
||||
|
||||
tries++;
|
||||
}
|
||||
while (TryFindGameWindow(process) == IntPtr.Zero);
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
throw new GameStartException("Could not read process information.");
|
||||
}
|
||||
while (TryFindGameWindow(process) == IntPtr.Zero);
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
throw new GameExitedException();
|
||||
}
|
||||
|
||||
if (!dontFixAcl)
|
||||
|
|
@ -309,13 +323,14 @@ namespace Dalamud.Injector
|
|||
/// <summary>
|
||||
/// Exception thrown when the process has exited before a window could be found.
|
||||
/// </summary>
|
||||
public class GameExitedException : Exception
|
||||
public class GameStartException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GameExitedException"/> class.
|
||||
/// Initializes a new instance of the <see cref="GameStartException"/> class.
|
||||
/// </summary>
|
||||
public GameExitedException()
|
||||
: base("Game exited prematurely.")
|
||||
/// <param name="message">The message to pass on.</param>
|
||||
public GameStartException(string? message = null)
|
||||
: base(message ?? "Game exited prematurely.")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue