Although the ArgumentList property has been added to System.Diagnostics.ProcessStartInfo as a way to relatively safely pass command line arguments, there is no simple, one-liner way to use this interface. This proposal seeks to add such an interface wherever a constructor or static function accepts the older string arguments initializer.
Applies to:
Changes requested:
S.D.P::Start(string fileName, IReadOnlyCollection<string> argumentList);S.D.PSI::new(string fileName, IReadOnlyCollection<string> argumentList);The fileName parameter retains the same semantics as in the other constructors. In line with how arguments is handled, the new argumentList parameter shall be copied to the internal ArgumentList property.
Non-goals:
Arguments.(How does the contribution thing works anyway? I guess I will open an issue first since I am on my phone.)
How does the contribution thing works anyway? I guess I will open an issue first since I am on my phone.)
New APIs should go through an API review process before it is approved to start implementing.
There is no simple, one-liner way to use this interface.
Personally I'm not a big fan of providing new APIs just to help people writing "one-liner" codes, because often they look better written out with newlines and spaces. It also could be done already like:
folded away because they're wrong 😅
new ProcessStartInfo("dotnet.exe") { ArgumentList = new Collection<string> { "build", "-c Release", "-f netcoreapp5.0" }}
// Just for comparison, using the existing (string, string) ctor:
new ProcessStartInfo("dotnet.exe", "build -c Release -f netcoreapp5.0")
Compared to the constructor version, I see little difference:
cs
new ProcessStartInfo("dotnet.exe", new Collection<string> { "build", "-c Release", "-f netcoreapp5.0" })
With that said though, perhaps passing in multiple arguments when launching a process is a common enough scenario (e.g. ProcessStartInfo already has a (string, string) ctor with the second parameter being the Arguments of the new instance) to warrant a new constructor for it.
Maybe argumentList could just be an IEnumerable<T> which the ctor fetches all the element in order and store it in the ArgumentList property?
Wait, the initializer list works? I thought it only worked on properties with a set; thing on it.
My request for this stemmed from powershell/powershell#1995, so it mainly is intended for these less sugary languages. Since new Process().startInfo.ArgumentList = blah… doesn't work I was thinking there's gotta be something better than just doing AddRange on it.
the initializer list works? I thought it only worked on properties with a set; thing on it.
They work for any type that implements IEnumerable<T> and that has an Add(T) method.
But yes, it only works on construction.
Actually, My bad. ArgumentList is a readonly property so you wouldn't be able to assign new Collection to it.... Well, that makes this suggestion better then 🙂
@Gnbrkm41 You don't need to assign new Collection when using a collection property initializer (provided that the backing property has a value set). I.e.
new ProcessStartInfo
{
ArgumentList = {
"arg1",
"arg2",
}
}
This would be nice because it would handle some escaping issues. For example, passing a path containing a space to a command-line tool.
This is a common source of bugs and I think writing a correct escaping algorithm is not entirely trivial.
I like this proposal and I think it's worth discussing it during API Review.
Since ProcessStartInfo.ArgumentsList is Collection<string> I think that we should make the new methods accept Collection<string> instead of IEnumerable<T> just to avoid copying the collection (it will force the callers to use it from the begining).
public class Process
{
public static System.Diagnostics.Process Start(string fileName, Collection<string> arguments);
}
public class ProcessStartInfo
{
public ProcessStartInfo(string fileName, Collection<string> arguments)
}
Process.Start()C#
namespace System.Diagnostics
{
public partial class Process
{
// Existing overloads:
// public static Process Start(string fileName);
// public static Process Start(string fileName, string arguments);
// public static Process Start(string fileName, string userName, SecureString password, string domain);
// public static Process Start(string fileName, string arguments, string userName, SecureString password, string domain);
// public static Process Start(ProcessStartInfo startInfo);
public static Process Start(string fileName, IEnumerable<string> arguments);
}
}
Most helpful comment
@Gnbrkm41 You don't need to assign
new Collectionwhen using a collection property initializer (provided that the backing property has a value set). I.e.