-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Update libraries for preview 7 #10000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
c382f19
7a21d12
ef3bedc
6974621
06a6f27
da347e2
5284fda
f777510
023ac94
d98c36e
59a58cc
709ed3e
f1acdf3
27869ec
c4dbf71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,3 +11,84 @@ Here's a summary of what's new in .NET Libraries in this preview release: | |
| ## Feature | ||
|
|
||
| Something about the feature | ||
|
|
||
| ## Launch Windows processes in new process group | ||
|
|
||
| For Windows, you can now use `ProcessStartInfo.CreateNewProcessGroup` to launch a process in a separate PG. This allows you to send isolated signals to child processes which could otherwise take down the parent without proper handling. Sending signals is convenient to avoid forceful termination. | ||
|
|
||
| ```csharp | ||
| using System; | ||
| using System.Diagnostics; | ||
| using System.IO; | ||
| using System.Runtime.InteropServices; | ||
| using System.Threading; | ||
|
|
||
| class Program | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The following example is complex, but correct. And it will most likely match the real world use case. |
||
| { | ||
| static void Main(string[] args) | ||
| { | ||
| bool isChildProcess = args.Length > 0 && args[0] == "child"; | ||
| if (!isChildProcess) | ||
| { | ||
| var psi = new ProcessStartInfo | ||
| { | ||
| FileName = Environment.ProcessPath, | ||
| Arguments = "child", | ||
| CreateNewProcessGroup = true, | ||
| }; | ||
|
|
||
| using Process process = Process.Start(psi)!; | ||
| Thread.Sleep(5_000); | ||
|
|
||
| GenerateConsoleCtrlEvent(CTRL_C_EVENT, (uint)process.Id); | ||
| process.WaitForExit(); | ||
|
|
||
| Console.WriteLine("Child process terminated gracefully, continue with the parent process logic if needed."); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we read the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wanted to show the need of properly dispose unmanaged resources (I'm open to better examples!). I don't think we need to read it back in the parent branch. |
||
| } | ||
| else | ||
| { | ||
| // you need to call SetConsoleCtrlHandler this way if you want to handle Ctrl+C in the child process, | ||
jozkee marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // see https://learn.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw#remarks | ||
| SetConsoleCtrlHandler((IntPtr)null, false); | ||
|
|
||
| Console.WriteLine("Greetings from the child process! I need to be gracefully terminated, send me a signal!"); | ||
|
|
||
| bool stop = false; | ||
|
|
||
| var registration = PosixSignalRegistration.Create(PosixSignal.SIGINT, ctx => | ||
| { | ||
| stop = true; | ||
| ctx.Cancel = true; | ||
| Console.WriteLine("Received CTRL+C, stopping..."); | ||
| }); | ||
|
|
||
| StreamWriter sw = File.AppendText("log.txt"); | ||
| int i = 0; | ||
| while (!stop) | ||
| { | ||
| Thread.Sleep(1000); | ||
| sw.WriteLine($"{++i}"); | ||
| Console.WriteLine($"Logging {i}..."); | ||
| } | ||
|
|
||
| // Clean up | ||
| sw.Dispose(); | ||
jozkee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| registration.Dispose(); | ||
|
|
||
| Console.WriteLine("Thanks for not killing me!"); | ||
| } | ||
| } | ||
|
|
||
| private const int CTRL_C_EVENT = 0; | ||
| private const int CTRL_BREAK_EVENT = 1; | ||
|
|
||
| [DllImport("kernel32.dll", SetLastError = true)] | ||
| [return: MarshalAs(UnmanagedType.Bool)] | ||
| private static extern bool SetConsoleCtrlHandler(IntPtr handler, [MarshalAs(UnmanagedType.Bool)] bool Add); | ||
|
|
||
| [DllImport("kernel32.dll", SetLastError = true)] | ||
| [return: MarshalAs(UnmanagedType.Bool)] | ||
| private static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId); | ||
| } | ||
| ``` | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dotnet/area-system-diagnostics-process