Skip to content

Commit d94dbac

Browse files
committed
Implement ProcessStartInfo.InheritHandles
1 parent 161f346 commit d94dbac

File tree

14 files changed

+464
-151
lines changed

14 files changed

+464
-151
lines changed

src/libraries/Common/src/Interop/Windows/Advapi32/Interop.ProcessOptions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@ internal static partial class StartupInfoOptions
4242
internal const int STARTF_USESHOWWINDOW = 0x00000001;
4343
internal const int STARTF_USESTDHANDLES = 0x00000100;
4444
internal const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
45+
internal const int EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
4546
internal const int CREATE_NO_WINDOW = 0x08000000;
4647
}
48+
49+
internal static partial class ProcThreadAttribute
50+
{
51+
internal const int HANDLE_LIST = 131074;
52+
}
4753
}
4854
}

src/libraries/Common/src/Interop/Windows/Kernel32/Interop.CreateProcess.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,21 @@ internal static unsafe partial bool CreateProcess(
2121
int dwCreationFlags,
2222
IntPtr lpEnvironment,
2323
string? lpCurrentDirectory,
24-
ref STARTUPINFO lpStartupInfo,
24+
ref STARTUPINFOEX lpStartupInfo,
2525
ref PROCESS_INFORMATION lpProcessInformation
2626
);
2727

28+
[LibraryImport(Libraries.Kernel32, EntryPoint = "InitializeProcThreadAttributeList", SetLastError = true)]
29+
[return: MarshalAs(UnmanagedType.Bool)]
30+
internal static unsafe partial bool InitializeProcThreadAttributeList(byte* lpAttributeList, uint dwAttributeCount, uint dwFlags, nuint* lpSize);
31+
32+
[LibraryImport(Libraries.Kernel32, EntryPoint = "UpdateProcThreadAttribute", SetLastError = true)]
33+
[return: MarshalAs(UnmanagedType.Bool)]
34+
internal static unsafe partial bool UpdateProcThreadAttribute(byte* lpAttributeList, uint dwFlags, nuint Attribute, Span<nint> lpValue, nuint cbSize, void* lpPreviousValue, nuint* lpReturnSize);
35+
36+
[LibraryImport(Libraries.Kernel32, EntryPoint = "DeleteProcThreadAttributeList", SetLastError = true)]
37+
internal static unsafe partial void DeleteProcThreadAttributeList(byte* lpAttributeList);
38+
2839
[StructLayout(LayoutKind.Sequential)]
2940
internal struct PROCESS_INFORMATION
3041
{
@@ -56,5 +67,12 @@ internal struct STARTUPINFO
5667
internal IntPtr hStdOutput;
5768
internal IntPtr hStdError;
5869
}
70+
71+
[StructLayout(LayoutKind.Sequential)]
72+
internal unsafe struct STARTUPINFOEX
73+
{
74+
internal STARTUPINFO StartupInfo;
75+
internal byte* AttributeList;
76+
}
5977
}
6078
}

src/libraries/System.Diagnostics.Process/ref/System.Diagnostics.Process.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ public ProcessStartInfo(string fileName, System.Collections.Generic.IEnumerable<
231231
[System.ComponentModel.EditorAttribute("System.Diagnostics.Design.StartFileNameEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
232232
[System.Diagnostics.CodeAnalysis.AllowNullAttribute]
233233
public string FileName { get { throw null; } set { } }
234+
public bool InheritHandles { get { throw null; } [System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")] set { } }
234235
[System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")]
235236
public bool LoadUserProfile { get { throw null; } set { } }
236237
[System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")]

src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,12 @@
306306
<data name="CantUseEnvVars" xml:space="preserve">
307307
<value>The Process object must have the UseShellExecute property set to false in order to use environment variables.</value>
308308
</data>
309+
<data name="CantDisableHandleInheritanceAndUseShellExecute" xml:space="preserve">
310+
<value>The Process object must have the UseShellExecute property set to false in order to disable handle inheritance.</value>
311+
</data>
312+
<data name="CantDisableHandleInheritanceAndUseUserName" xml:space="preserve">
313+
<value>The Process object must have the InheritHandles property set to true in order to start a process as a user.</value>
314+
</data>
309315
<data name="UseShellExecuteNotSupported" xml:space="preserve">
310316
<value>UseShellExecute is not supported on this platform.</value>
311317
</data>

src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Win32.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ private unsafe bool StartWithShellExecuteEx(ProcessStartInfo startInfo)
4747
if (startInfo._environmentVariables != null)
4848
throw new InvalidOperationException(SR.CantUseEnvVars);
4949

50+
if (!startInfo.InheritHandles)
51+
throw new InvalidOperationException(SR.CantDisableHandleInheritanceAndUseShellExecute);
52+
5053
string arguments = startInfo.BuildArguments();
5154

5255
fixed (char* fileName = startInfo.FileName.Length > 0 ? startInfo.FileName : null)

0 commit comments

Comments
 (0)