Skip to content

Commit

Permalink
progress on the Restarter.cs
Browse files Browse the repository at this point in the history
ahh why is System.Management so dumb and failing to load at runtime. This makes no sense at all!!!
  • Loading branch information
Rexicon226 committed Jan 8, 2024
1 parent 2562320 commit f10909d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 27 deletions.
17 changes: 13 additions & 4 deletions src/SpaceWarp.UI/UI/ModList/ModListController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Diagnostics;
using System.Diagnostics;
using BepInEx;
using I2.Loc;
using SpaceWarp.API.Assets;
Expand Down Expand Up @@ -351,21 +351,30 @@ private void SetupButtons()
_applyChangesButton.style.display = DisplayStyle.None;
_applyChangesButton.RegisterCallback<ClickEvent>(_ =>
{
int currentPid = Process.GetCurrentProcess().Id;

// We call on restarter to kill the current process
// and it will call the restarter to restarter.
var restarterPath = Path.Combine(
SpaceWarpPlugin.Instance.SWMetadata.Folder.FullName,
"restarter",
"SpaceWarpRestarter.exe"
);
Modules.UI.Instance.ModuleLogger.LogDebug($"Restarter path: {restarterPath}");

var restarter = new Process();

// We give the restarter the current_pid so that it can kill it.
restarter.StartInfo = new ProcessStartInfo(restarterPath)
{
Arguments = Environment.CommandLine
Arguments = $"\"{Environment.CommandLine}\" {currentPid}"
};
restarter.Start();

Application.Quit();
// Hang the current process so that the restarter can kill it.
while (true)
{
Thread.Sleep(1000);
}
});

_detailsSourceLink.RegisterCallback<ClickEvent>(_ =>
Expand Down
81 changes: 59 additions & 22 deletions src/SpaceWarpRestarter/Restarter.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,77 @@
using System.Diagnostics;
using System.Reflection;
using System.Management;

// Can only run on Windows
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
{
Console.WriteLine("This can only run on Windows.");
Environment.Exit(1);
}

if (args.Length < 1)
{
Console.WriteLine(
$"Usage: {Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location)} <path to KSP2_x64.exe> " +
$"[optional arguments]"
$"Usage: {Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location)}.exe " +
$"<target process id> " +
$"[optional arguments that will be passed to KSP2_x64.exe]"
);
Environment.Exit(1);
}

var processPath = args[0];
var processName = Path.GetFileNameWithoutExtension(processPath);
var targetPid = args[0];
var processArgs = string.Join(" ", args.Length > 1 ? args[1..] : Array.Empty<string>());

Console.WriteLine($"Waiting for {processName} to exit...");

while (true)
// Get the path to the KSP2_x64.exe
var processModule = Process.GetProcessById(int.Parse(targetPid)).MainModule;
if (processModule != null)
{
if (Process.GetProcessesByName(processName).Length == 0)
var processPath = processModule.FileName;

KillProc(int.Parse(targetPid));

// Launch the process
var ksp2Process = new Process
{
try
{
Console.WriteLine($"{processName}.exe is not running. Attempting to start the process...");
Process.Start("cmd.exe", $"/C \"{processPath}\" {processArgs}");
Console.WriteLine($"{processName}.exe started successfully.");
break;
}
catch (Exception ex)
StartInfo = new ProcessStartInfo
{
Console.WriteLine($"An error occurred while starting {processName}.exe: {ex.Message}");
Environment.Exit(1);
FileName = processPath,
Arguments = processArgs,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
}
else
};

// Start the ksp2_process and detach from it
ksp2Process.Start();
ksp2Process.Dispose();
} else {
Console.WriteLine("Could not find the process.");
Environment.Exit(1);
}

Environment.Exit(0);

// Will recursively kill all child processes of the given process and the process itself
void KillProc(int pid)
{
var process = Process.GetProcessById(pid);

// We already guaranteed that this will only run on Windows
#pragma warning disable CA1416
var searcher = new ManagementObjectSearcher(
$"SELECT * " +
$"FROM Win32_Process " +
$"WHERE ParentProcessId={pid}"
);

foreach (var child in searcher.Get())
{
Thread.Sleep(500);
KillProc(int.Parse(child["ProcessId"].ToString() ?? throw new InvalidOperationException()));
}
}

process.Kill();
#pragma warning restore CA1416
}
4 changes: 3 additions & 1 deletion src/SpaceWarpRestarter/SpaceWarpRestarter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>SpaceWarpRestarter</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
</Project>

0 comments on commit f10909d

Please sign in to comment.