| File: Utilities\ProcessUtilities.cs | Web Access |
| Project: src\sdk\src\Dotnet.Watch\Watch\Microsoft.DotNet.HotReload.Watch.csproj (Microsoft.DotNet.HotReload.Watch) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Microsoft.DotNet.Watch; internal static class ProcessUtilities { public static string? SendWindowsCtrlCEvent(int processId) { const uint CTRL_C_EVENT = 0; // Doc: // "The process identifier of the new process is also the process group identifier of a new process group. // // The process group includes all processes that are descendants of the root process. // Only those processes in the group that share the same console as the calling process receive the signal. // In other words, if a process in the group creates a new console, that process does not receive the signal, // nor do its descendants. // // If this parameter is zero, the signal is generated in all processes that share the console of the calling process." return GenerateConsoleCtrlEvent(CTRL_C_EVENT, (uint)processId) ? null : GetLastPInvokeErrorMessage(); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId); } private static string GetLastPInvokeErrorMessage() { var error = Marshal.GetLastPInvokeError(); #if NET10_0_OR_GREATER return $"{Marshal.GetPInvokeErrorMessage(error)} (code {error})"; #else return $"error code {error}"; #endif } }