diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs
index 1539a18e0..48d86d160 100644
--- a/Dalamud.Injector/EntryPoint.cs
+++ b/Dalamud.Injector/EntryPoint.cs
@@ -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);
diff --git a/Dalamud.Injector/NativeAclFix.cs b/Dalamud.Injector/NativeAclFix.cs
index 1200bfcf7..5f14bce26 100644
--- a/Dalamud.Injector/NativeAclFix.cs
+++ b/Dalamud.Injector/NativeAclFix.cs
@@ -24,13 +24,14 @@ namespace Dalamud.Injector
/// Arguments to pass to the executable file.
/// Don't actually fix the ACL.
/// Action to execute before the process is started.
+ /// Wait for the game window to be ready before proceeding.
/// The started process.
/// Thrown when a win32 error occurs.
- /// Thrown when the process did not start correctly.
- public static Process LaunchGame(string workingDir, string exePath, string arguments, bool dontFixAcl, Action beforeResume)
+ /// Thrown when the process did not start correctly.
+ public static Process LaunchGame(string workingDir, string exePath, string arguments, bool dontFixAcl, Action 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
///
/// Exception thrown when the process has exited before a window could be found.
///
- public class GameExitedException : Exception
+ public class GameStartException : Exception
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- public GameExitedException()
- : base("Game exited prematurely.")
+ /// The message to pass on.
+ public GameStartException(string? message = null)
+ : base(message ?? "Game exited prematurely.")
{
}
}