This commit is contained in:
commit
b54acec2f2
66 changed files with 5135 additions and 0 deletions
79
src/Process/Execution/ProcessHandle.Windows.cs
Normal file
79
src/Process/Execution/ProcessHandle.Windows.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
using System.Diagnostics;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text;
|
||||
|
||||
namespace Geekeey.Extensions.Process;
|
||||
|
||||
internal partial class ProcessHandle
|
||||
{
|
||||
private const string CSharpSourceText =
|
||||
"""
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool FreeConsole();
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool AttachConsole(uint p);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool SetConsoleCtrlHandler(uint p, bool a);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool GenerateConsoleCtrlEvent(uint e, uint p);
|
||||
|
||||
public static int NotifyCtrlEvent(uint pid, uint sig)
|
||||
{
|
||||
// detach from the current console, if one is attached to the process.
|
||||
FreeConsole();
|
||||
|
||||
var success =
|
||||
// attach to the target process group
|
||||
AttachConsole(pid) &&
|
||||
// set to ignore signals on self, so the proper exit code can be return
|
||||
SetConsoleCtrlHandler(0, true) &&
|
||||
// send the signal to the process group
|
||||
GenerateConsoleCtrlEvent(sig, 0);
|
||||
|
||||
return success ? 0 : Marshal.GetLastWin32Error();
|
||||
}
|
||||
""";
|
||||
|
||||
private const string PowerShellSourceText =
|
||||
"""
|
||||
Add-Type -Namespace 'Win32' -Name 'Notify' -Language CSharp -MemberDefinition '{0}';
|
||||
exit [Win32.Notify]::NotifyCtrlEvent({1}, {2})
|
||||
""";
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private static bool SendCtrlSignal(int processId, ConsoleCtrlEvent ctrl)
|
||||
{
|
||||
using var process = new System.Diagnostics.Process();
|
||||
|
||||
var text = string.Format(PowerShellSourceText, CSharpSourceText, processId, (uint)ctrl);
|
||||
text = Convert.ToBase64String(Encoding.Unicode.GetBytes(text));
|
||||
|
||||
process.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "powershell.exe",
|
||||
Arguments = $"-NoLogo -NoProfile -ExecutionPolicy Bypass -EncodedCommand {text}",
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
if (!process.Start())
|
||||
return false;
|
||||
|
||||
if (!process.WaitForExit(30_000))
|
||||
return false;
|
||||
|
||||
return process.ExitCode == 0;
|
||||
}
|
||||
|
||||
internal enum ConsoleCtrlEvent
|
||||
{
|
||||
CTRL_C_EVENT = 0, // SIGINT
|
||||
CTRL_BREAK_EVENT = 1, // SIGQUIT
|
||||
CTRL_CLOSE_EVENT = 2, // SIGHUP
|
||||
CTRL_LOGOFF_EVENT = 5, // SIGHUP
|
||||
CTRL_SHUTDOWN_EVENT = 6, // SIGTERM
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue