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
[API Proposal]: ProcessStartInfo.CreationFlags
(for Windows only)
#71515
Comments
Tagging subscribers to this area: @dotnet/area-system-diagnostics-process Issue DetailsBackground and motivationThe Of course, you can P/Invoke I propose that The implementation effort here should be extremely minimal while providing huge convenience to people who need to set process creation flags on Windows. API Proposalnamespace System.Diagnostics.Process;
public sealed partial class ProcessStartInfo
{
[SupportedOSPlatform("windows")]
public uint CreationFlags { get; set; }
}
API Usagevar info = new ProcessStartInfo(fileName);
foreach (var arg in args)
info.ArgumentList.Add(arg);
info.CreationFlags = 0x4 /* CREATE_SUSPENDED */;
using var proc = new Process
{
StartInfo = info,
};
proc.Start();
// Do some Win32-specific stuff that ultimately causes the process to be woken up.
proc.WaitForExit(); Alternative DesignsNone. RisksNone.
|
There are number of other Windows-specific parameters that ProcessStartInfo does not expose. For example, all parameters from https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute If one needs a full control over the Windows-specific parameters, it is better to PInvoke |
Yes, but these aren't simple flags. The complexity of exposing this functionality would be considerably higher, and I'm also not sure to what extent anyone actually needs/wants them. By contrast, I have 3 separate projects where I have the need to add extra process creation flags.
This ignores what I wrote in the motivation section:
I think it's unreasonable to ask people to reimplement all of that when exposing a I'll also add that there's precedent in other languages: |
Perhaps there should be a constructor from SafeProcessHandle similar to Socket constructor from SafeSockegHandle: |
That would not actually address any of the issues outlined in the motivation section above. |
Another problem that arises is that there is no way to go from a process handle to a * Notably, there is no API to retrieve the process ID from a pseudo-handle allocated by |
Constructing a
I do not see how you could possibly achieve that with in any way with an existing handle? If you have a handle, it is too late. But I definitely see the value in the idea of constructing Process objects from handles - there are cases where -- For the actual proposal in this issue, as others said I think there are extremely few cases where all you would want are the flags, but not the other options, the primary one being tightly controlling handle inheritance. Another one that's almost always required is STARTUPINFO::dwFlags. Creating processes just has too many knobs - and I imagine there are as many various knobs in Linux, in Mac... |
I have a bunch of use cases right off the bat:
I think we can address those knobs as use cases come up. It doesn't seem to me that they would conflict with this proposal. |
Yeah. I didn't word it as clearly as I'd hoped, but I was intending to say that being able to go from handle -> Process would be a nice addition, though it wouldn't solve the root issue mentioned by the OP: being able to provide creation flags and still take advantage of the
It should be noted that |
There are lots of ways to get at the main thread or simply resume it while ignoring the returned handle from |
But that is not my point - and from what I understand, not the point of other posters in this thread. Besides, every listed use case idea in this list would require at least some amount of extra PInvoke after creation. |
But how do you actually figure that? I've put forth several real use cases where the only thing needed from the
But it is enough for those cases I listed. I am not trying to solve every process creation problem under the sun, just a fairly reasonable subset for Windows. And, judging by the precedent in other languages that I mentioned above, I'm not the only person who thinks it's a reasonable subset.
All of which are quite trivial, but that's besides the point. The principal motivation for this API proposal is the maintenance nightmare that would result in the alternative solution: I would be copying almost all of the It's plainly untenable. |
Python exposes |
Sure. Just to be clear, I'm not at all against exposing more process creation options. But I see e.g. Since what's being asked for here is very simple and straightforward to implement, and won't conflict with future efforts to add more similar functionality, I'd just like to avoid scope creep so that this has a chance of actually happening. |
It is not obvious that it won't conflict. We prefer to review API proposals with full solution to the problem, so that we can see what the full API shape may look like eventually. We have number of examples where we failed to follow this principle, added an API in one version of the runtime, and added a new API in next version that is duplicate or inconsistent with the one added earlier. |
I'm just not seeing it, I suppose. I also said in the issue description that I'm okay with individual properties for each flag. The 5 that I mentioned here are the ones I would personally really like to see (I could also see arguments for
That is understandable, but at the same time, "full solution to the problem" seems kind of nebulous here. It doesn't seem like anyone actually has an idea what the proposal should cover in full, so even if I were willing to spec out a full API, I wouldn't know what to do. It also seems to conflict with the notion that API proposals should be driven by real world needs. I've seen many cases where an API proposal gets shot down (and rightfully so) because it's either a solution looking for a problem, or there isn't a compelling enough use case. |
This proposal is based on the premise that there are platform-specific details that one needs to pass into the OS API that backs
It is a long tail, but I believe that you will be able to find some real-world need for any of these platform-specific details. For example, github search shows number of instance of |
Well, not exactly. Like I said, I'm open to Due to the nature of the
There's also a whole bunch of stuff on
I think we use |
btw does this all mean that launching console apps using Process.Start on Windows silently is no longer an option (for NET6.0 and beyond)? |
Can you elaborate? It's not obvious to me how that's connected to the proposal here; no functionality would be taken away. |
Sure. This might be unrelated as I don't have an understanding of how the Process.Start works internally. Here's a case: I have a NET6.0 WPF app that needs to launch a console app and keep it hidden. The WPF app runs on Windows and so it should be able to control this behavior in a way like below: In NETFX this works but I don't see this working in NET6.0. So given that Process.Start in NET6.0 is cross-platform (and given some other conversations like PowerShell/PowerShell#3028) I thought that maybe the ability to run console apps hidden in Process.Start was a Windows-only feature. If that's the case then I suppose one cannot achieve silent/hidden launch of console apps in NET6.0, right? If these assumptions are wrong then I apologize for the intrusion! |
@danielkornev I have to admit I'm a bit confused at what the concern is still, but, if
It is.
You should be able to achieve that on Windows just like with .NET Framework. |
By the way, @jkotas ping re: my questions in #71515 (comment). |
It argues that the
I think so. |
The approach of creating a Process object form an existing process handle sounds more powerful to me, allows for more interoperability and avoids OS-exclusive APIs. |
As I mentioned earlier, it does not actually solve the problem that this proposal is trying to solve. |
I think it can be an option if it is accompanied by several helper APIs like an API to create the input/output redirection streams to address your concern. Yes, such APIs would be OS-exclusive, but it is likely going to be much smaller public surface than all possible APIs to customize the process creation. |
That's a good point. I can include that as a possible alternative in the proposal. It would need to also cover argument pasting and environment block creation, and the hypothetical |
Background and motivation
The
Process
API currently provides no way to control the process creation flags used on Windows. This is unfortunate as there are a number of flags that are quite useful, such asCREATE_NEW_PROCESS_GROUP
,CREATE_SUSPENDED
, andDEBUG_PROCESS
.Of course, you can P/Invoke
CreateProcessW
to use these flags and this works for extremely trivial use cases. But as soon as you need anything more than "just run an executable with these flags", things get hairy: You have to reimplement environment block construction,string[]
->string
command line pasting, and standard I/O piping. Not a fun experience at all.I propose that
ProcessStartInfo
simply gets a Windows-specificCreationFlags
property to set the process creation flags. These would just get OR'd with whichever flagsProcess
itself needs to set based on other properties (e.g.CREATE_NO_WINDOW
).The implementation effort here should be extremely minimal while providing huge convenience to people who need to set process creation flags on Windows.
API Proposal
CreateProcessW
might do; the assumption would be that anyone using this property knows what they're doing.PlatformNotSupportedException
on non-Windows platforms vs just being ignored.CreationFlags
could be strongly typed as an enum, but I'm not sure the BCL should be in the business of exposing such an enum and keeping it up to date with the Win32 API.API Usage
Alternative Designs
Individual properties for each flag is also an option.
Risks
None.
The text was updated successfully, but these errors were encountered: