chore: rework windows signal notify
This commit is contained in:
parent
b54acec2f2
commit
b7517a7fee
3 changed files with 50 additions and 30 deletions
38
src/Process.Win.Notify/Interop.cs
Normal file
38
src/Process.Win.Notify/Interop.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Geekeey.Extensions.Process.Win.Notify;
|
||||||
|
|
||||||
|
internal static class Interop
|
||||||
|
{
|
||||||
|
// ReSharper disable MemberHidesStaticFromOuterClass
|
||||||
|
|
||||||
|
internal static class Libraries
|
||||||
|
{
|
||||||
|
internal const string Kernel32 = "kernel32.dll";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class Kernel32
|
||||||
|
{
|
||||||
|
public delegate bool ConsoleCtrlDelegate(uint dwCtrlEvent);
|
||||||
|
|
||||||
|
[DllImport(Libraries.Kernel32)]
|
||||||
|
[SuppressGCTransition]
|
||||||
|
internal static extern int GetLastError();
|
||||||
|
|
||||||
|
[DllImport(Libraries.Kernel32)]
|
||||||
|
[SuppressGCTransition]
|
||||||
|
public static extern bool FreeConsole();
|
||||||
|
|
||||||
|
[DllImport(Libraries.Kernel32)]
|
||||||
|
[SuppressGCTransition]
|
||||||
|
public static extern bool AttachConsole(uint dwProcessId);
|
||||||
|
|
||||||
|
[DllImport(Libraries.Kernel32)]
|
||||||
|
[SuppressGCTransition]
|
||||||
|
public static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate? handlerRoutine, bool add);
|
||||||
|
|
||||||
|
[DllImport(Libraries.Kernel32)]
|
||||||
|
[SuppressGCTransition]
|
||||||
|
public static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
|
@ -1,43 +1,26 @@
|
||||||
using System.Globalization;
|
namespace Geekeey.Extensions.Process.Win.Notify;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Geekeey.Extensions.Process.Win.Notify;
|
|
||||||
|
|
||||||
internal static class Interop
|
|
||||||
{
|
|
||||||
public delegate bool ConsoleCtrlDelegate(uint dwCtrlEvent);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern bool FreeConsole();
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern bool AttachConsole(uint dwProcessId);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate? handlerRoutine, bool add);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
public static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static class Program
|
internal static class Program
|
||||||
{
|
{
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
{
|
{
|
||||||
var processId = uint.Parse(args[0], CultureInfo.InvariantCulture);
|
var processId = uint.Parse(args[0]);
|
||||||
var signal = uint.Parse(args[1], CultureInfo.InvariantCulture);
|
var signal = uint.Parse(args[1]);
|
||||||
|
|
||||||
// detach from the current console, if one is attached to the process.
|
// detach from the current console, if one is attached to the process.
|
||||||
Interop.FreeConsole();
|
Interop.Kernel32.FreeConsole();
|
||||||
|
|
||||||
var success =
|
var success =
|
||||||
// attach to the target process group
|
// attach to the target process group
|
||||||
Interop.AttachConsole(processId) &&
|
Interop.Kernel32.AttachConsole(processId) &&
|
||||||
// set to ignore signals on self, so the proper exit code can be return
|
// set to ignore signals on self, so the proper exit code can be return
|
||||||
Interop.SetConsoleCtrlHandler(null, true) &&
|
Interop.Kernel32.SetConsoleCtrlHandler(null, true) &&
|
||||||
// send the signal to the process group
|
// send the signal to the process group
|
||||||
Interop.GenerateConsoleCtrlEvent(signal, 0);
|
Interop.Kernel32.GenerateConsoleCtrlEvent(signal, 0);
|
||||||
|
|
||||||
return success ? 0 : Marshal.GetLastPInvokeError();
|
// we can use the kernel32 GetLastError here, instead of relaying on `Marshal.GetLastWin32Error`, because we
|
||||||
|
// are compiling this with a compiler which does not include gc. This can not cause gc pause which tampers with
|
||||||
|
// the last error code.
|
||||||
|
return success ? 0 : Interop.Kernel32.GetLastError();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue