mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +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");
|
Log.Error("[HOOKS] RewriteRemoteEntryPointW failed");
|
||||||
throw new Exception("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")
|
if (!withoutDalamud && mode == "inject")
|
||||||
{
|
{
|
||||||
var startInfo = AdjustStartInfo(dalamudStartInfo, gamePath);
|
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="arguments">Arguments to pass to the executable file.</param>
|
||||||
/// <param name="dontFixAcl">Don't actually fix the ACL.</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="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>
|
/// <returns>The started process.</returns>
|
||||||
/// <exception cref="Win32Exception">Thrown when a win32 error occurs.</exception>
|
/// <exception cref="Win32Exception">Thrown when a win32 error occurs.</exception>
|
||||||
/// <exception cref="GameExitedException">Thrown when the process did not start correctly.</exception>
|
/// <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)
|
public static Process LaunchGame(string workingDir, string exePath, string arguments, bool dontFixAcl, Action<Process> beforeResume, bool waitForGameWindow = true)
|
||||||
{
|
{
|
||||||
Process process = null;
|
Process process = null;
|
||||||
|
|
||||||
var psecDesc = IntPtr.Zero;
|
var psecDesc = IntPtr.Zero;
|
||||||
if (!dontFixAcl)
|
if (!dontFixAcl)
|
||||||
{
|
{
|
||||||
|
|
@ -121,19 +122,32 @@ namespace Dalamud.Injector
|
||||||
PInvoke.ResumeThread(lpProcessInformation.hThread);
|
PInvoke.ResumeThread(lpProcessInformation.hThread);
|
||||||
|
|
||||||
// Ensure that the game main window is prepared
|
// 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)
|
if (!dontFixAcl)
|
||||||
|
|
@ -309,13 +323,14 @@ namespace Dalamud.Injector
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Exception thrown when the process has exited before a window could be found.
|
/// Exception thrown when the process has exited before a window could be found.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GameExitedException : Exception
|
public class GameStartException : Exception
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="GameExitedException"/> class.
|
/// Initializes a new instance of the <see cref="GameStartException"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameExitedException()
|
/// <param name="message">The message to pass on.</param>
|
||||||
: base("Game exited prematurely.")
|
public GameStartException(string? message = null)
|
||||||
|
: base(message ?? "Game exited prematurely.")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue