KillOnParentExit rejects the Microsoft Store PowerShell execution alias with access denied
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- csharp
- Lĩnh vực
- backend, operating-systems
Hướng nghiên cứu
Start with SafeProcessHandle.StartCore in src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Windows.cs, the Windows startup path linked in the report. Reproduce the failure with the supplied program on Windows using the Store PowerShell alias, then compare it with the physical executable and the existing bounded replacement-job retry. Done when the alias starts with KillOnParentExit enabled, or the API reports and documents the unsupported case clearly.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description
ProcessStartInfo.KillOnParentExit=true causes Process.Start to reject the Microsoft Store PowerShell execution alias with native error 5 on .NET 11 GA. The same alias starts successfully when the option is false, including suspended creation. Applications that enable parent-exit cleanup therefore cannot launch this otherwise working executable.
Reproduction Steps
Install Microsoft Store PowerShell (tested package Microsoft.PowerShell 7.6.9.0 x64) with its execution alias enabled. Create a console project targeting net11.0 with implicit usings and nullable enabled, and replace Program.cs with:
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
if (!OperatingSystem.IsWindows()) return;
Console.WriteLine($"Runtime {Environment.Version}; {RuntimeInformation.OSDescription}; {RuntimeInformation.ProcessArchitecture}");
var executable = args.Length > 0 ? Path.GetFullPath(args[0]) : Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft", "WindowsApps", "Microsoft.PowerShell_8wekyb3d8bbwe", "pwsh.exe");
using var launcher = Process.GetCurrentProcess();
using var outer = JoinJob(launcher);
using var inner = JoinJob(launcher);
foreach (var suspended in new[] { false, true })
foreach (var lifetime in new[] { false, true, false })
{
using var child = new Process { StartInfo = new ProcessStartInfo(executable)
{
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
InheritedHandles = [],
CreateNoWindow = true,
CreateNewProcessGroup = true,
KillOnParentExit = lifetime,
StartSuspended = suspended,
ArgumentList = { "--version" },
}};
try
{
child.Start();
if (suspended) child.SafeHandle.Resume();
child.StandardInput.Close();
var stdout = child.StandardOutput.ReadToEndAsync();
var stderr = child.StandardError.ReadToEndAsync();
await Task.WhenAll(child.WaitForExitAsync(), stdout, stderr).WaitAsync(TimeSpan.FromSeconds(10));
Console.WriteLine($"KillOnParentExit={lifetime}; StartSuspended={suspended}; Exit={child.ExitCode}; Output={(await stdout).Trim()}; Error={(await stderr).Trim()}");
}
catch (Win32Exception exception)
{
Console.WriteLine($"KillOnParentExit={lifetime}; StartSuspended={suspended}; NativeErrorCode={exception.NativeErrorCode}; {exception.Message}");
}
finally
{
try
{
if (!child.HasExited) child.Kill();
await child.WaitForExitAsync().WaitAsync(TimeSpan.FromSeconds(5));
}
catch (InvalidOperationException) { } // Start failed; there is no owned child.
}
}
static SafeFileHandle JoinJob(Process launcher)
{
// Plain, non-killing jobs; no resource limits, UI limits or breakaway changes.
var job = Native.CreateJobObjectW(0, null);
if (job.IsInvalid || !Native.AssignProcessToJobObject(job, launcher.SafeHandle))
{
var error = Marshal.GetLastPInvokeError();
job.Dispose();
throw new Win32Exception(error);
}
return job;
}
static class Native
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
internal static extern SafeFileHandle CreateJobObjectW(nint attributes, string? name);
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool AssignProcessToJobObject(SafeFileHandle job, SafeProcessHandle process);
}
Run dotnet run with SDK 11.0.100. The default executable is the package-specific alias beneath the current user's local application data. An explicit executable path can instead be passed after --.
The program joins two ordinary, non-killing jobs before launching children. It neither changes pre-existing jobs nor requests breakaway. Every successfully created child is waited and cleaned up through its own process handle.
Expected behavior
The alias should start with parent-exit cleanup enabled, or the API should explicitly document and identify this unsupported executable type.
Actual behavior
Both StartSuspended=false and StartSuspended=true produce this false/true/false sequence:
KillOnParentExit=False: Exit=0; Output=PowerShell 7.6.9
KillOnParentExit=True: Win32Exception; NativeErrorCode=5; Access is denied.
KillOnParentExit=False: Exit=0; Output=PowerShell 7.6.9
The exception comes from SafeProcessHandle.StartCore during Process.Start. The runtime's bounded replacement-job retry does not make the alias start.
With the same redirected streams, restricted inheritance, process group, and nested jobs, the physical C:\Program Files\PowerShell\7\pwsh.exe (also PowerShell 7.6.9) succeeds for every combination. dotnet.exe --version and cmd.exe /d /c echo probe-ok also succeed with and without the option. This report claims the tested alias failure; it does not infer a general Windows job limitation.
Regression?
Not established. This is distinct from #134990: ordinary executable launches after containment changes now work in the GA runtime.
Known Workarounds
Launching the physical PowerShell executable succeeds. Disabling KillOnParentExit lets the alias start but removes the requested lifetime guarantee.
Configuration
- SDK: 11.0.100.
- Runtime: 11.0.0, commit
297acf930f. - OS:
Microsoft Windows 10.0.26300, x64. - Microsoft Store package:
Microsoft.PowerShell 7.6.9.0, x64. - PowerShell output:
PowerShell 7.6.9.
Other information
Checked open and closed runtime issues for KillOnParentExit with alias, package, WindowsApps, and PowerShell terms. The Windows startup implementation on v11.0.0 and main at 719ca2546bd31a54244731185c55c8fc208204bf still supplies the lifetime job through the extended startup attributes. No alias-specific fix was found in main or the .NET 11 release notes.
Discovered while investigating ModularPipelines #6302. Please support this alias launch with KillOnParentExit, or document its restriction with an actionable error.
- Ngôn ngữ chính
- C#
- Star
- 18.4k
- Fork
- 5.8k
- Merge trung bình
- 2 ngày 19 giờ
- Pull request đã merge (30 ngày)
- 590
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của dotnet/runtime
-
area-Setup untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
dotnet/runtime#137376 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area-System.Memory untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
dotnet/runtime#137334 · 4 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
ImmutableSortedSet<T>.Builder: enumerating through IEnumerable<T> doesn't throw on modification and can return wrong itemsCó thể đã có người làm @aw0lid đã nhận 3 ngày trước. Đang mởarea-System.Collections
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
dotnet/runtime#137167 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
DbTransaction.SupportsSavepoints docs say Release/ReleaseAsync are expected to throw, but they are no-ops by designCó thể đã có người làm @alaricd đã nhận 7 ngày trước. Đang mởarea-System.Transactions untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
dotnet/runtime#137040 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
FileSystemGlobbing: Matcher throws ArgumentOutOfRangeException when the rootDir is the same value as the fileCó thể đã có người làm @makazeu đã nhận 7 ngày trước. Đang mởarea-Extensions-FileSystem
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
dotnet/runtime#136989 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của dotnet/runtime
Issue tương tự
-
bug emitter:client:csharp
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
microsoft/typespec#12572 · 1 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
needs-area-label
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 2 ngày
-
AWS Lambda: KeyNotFoundException drops HTTP-triggered transactions when allowAllHeaders is disabledĐang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
newrelic/newrelic-dotnet-agent#3949 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area-networking
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
dotnet/aspnetcore#70545 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 87/100
Maintainer thường phản hồi trong vòng 1 ngày