Fix Kill command on Linux (Closes #1564) (#1569)

Co-authored-by: Alexandru Macocian <amacocian@microsoft.com>
This commit is contained in:
2026-06-30 14:19:50 +02:00
parent d553aadead
commit 1e8c2e44e2
4 changed files with 40 additions and 12 deletions
@@ -536,18 +536,7 @@ internal sealed class ApplicationLauncher(
var scopedLogger = this.logger.CreateScopedLogger();
try
{
var process = guildWarsApplicationLaunchContext.GuildWarsProcess;
if (
process.MainModule?.FileName is not null
&& process.MainModule.FileName.Contains(
"Gw.exe",
StringComparison.OrdinalIgnoreCase
)
)
{
process.Kill(true);
return;
}
this.guildWarsProcessFinder.KillProcess(guildWarsApplicationLaunchContext);
}
catch (Exception e)
when (e.Message.Contains(
@@ -52,6 +52,19 @@ public sealed class GuildWarsProcessFinder(
return this.FindProcesses(configuration).FirstOrDefault();
}
/// <summary>
/// Terminates the Wine-hosted Guild Wars process tree.
/// The process was already validated as a Gw.exe Wine process during discovery,
/// so we kill it directly. On Linux the process exposed by the context is the
/// Wine loader hosting Gw.exe; its <see cref="Process.MainModule"/> therefore
/// points at the Wine loader rather than Gw.exe, which is why platform-agnostic
/// name checks cannot be used here.
/// </summary>
public void KillProcess(GuildWarsApplicationLaunchContext guildWarsApplicationLaunchContext)
{
guildWarsApplicationLaunchContext.GuildWarsProcess.Kill(entireProcessTree: true);
}
public IEnumerable<GuildWarsApplicationLaunchContext?> FindProcesses(
params LaunchConfigurationWithCredentials[] configurations
)
@@ -30,4 +30,12 @@ public interface IGuildWarsProcessFinder
IEnumerable<GuildWarsApplicationLaunchContext?> FindProcesses(
params LaunchConfigurationWithCredentials[] configurations
);
/// <summary>
/// Terminates the Guild Wars process associated with the given launch context.
/// Implementations are responsible for handling platform-specific process layouts
/// (e.g. Wine-hosted processes on Linux). May throw, allowing the caller to handle
/// platform-specific failures such as insufficient privileges.
/// </summary>
void KillProcess(GuildWarsApplicationLaunchContext guildWarsApplicationLaunchContext);
}
@@ -28,6 +28,24 @@ public sealed class GuildWarsProcessFinder : IGuildWarsProcessFinder
return this.FindProcesses(configuration).FirstOrDefault();
}
/// <summary>
/// Terminates the Guild Wars process tree. Guards against killing an unrelated
/// process by verifying the main module is Gw.exe. Reading the main module of an
/// elevated process throws a <see cref="Win32Exception"/>, which is propagated so
/// the caller can fall back to a direct kill or request elevation.
/// </summary>
public void KillProcess(GuildWarsApplicationLaunchContext guildWarsApplicationLaunchContext)
{
var process = guildWarsApplicationLaunchContext.GuildWarsProcess;
if (
process.MainModule?.FileName is not null
&& process.MainModule.FileName.Contains("Gw.exe", StringComparison.OrdinalIgnoreCase)
)
{
process.Kill(true);
}
}
public IEnumerable<GuildWarsApplicationLaunchContext?> FindProcesses(
params LaunchConfigurationWithCredentials[] configurations
)