Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/ArgumentBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,35 @@ public static string EscapeAndConcatenateCommandAndArgArrayForProcessStart(
return sb.ToString();
}

/// <summary>
/// Undo the processing which took place to create string[] args in Main, so that the next process will receive the same string[] args.
/// </summary>
/// <remarks>
/// Note that pwsh does not require any special escaping of arguments. We can simply concatenate the list of strings with a space between each.
/// </remarks>
/// <param name="command">The base command.</param>
/// <param name="args">List of arguments to escape.</param>
/// <returns>An escaped string of the <paramref name="command"/> and <paramref name="args"/>.</returns>
public static string ConcatenateCommandAndArgArrayForPwshProcessStart(
string? command,
string[]? args)
{
var sb = new ValueStringBuilder(stackalloc char[256]);

sb.Append(command);

if (args is not null)
{
for (var i = 0; i < args.Length; i++)
{
sb.Append(Space);
sb.Append(args[i]);
}
}

return sb.ToString();
}

/// <summary>
/// Undo the processing which took place to create string[] args in Main, so that the next process will receive the same string[] args.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/CommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public async Task<int> RunAsync(string name, string cmd, string[]? args)
ArgumentBuilder.EscapeAndConcatenateCommandAndArgArrayForCmdProcessStart(cmd, args),
"\"");
}
else if (_processContext.Shell.Equals("pwsh", StringComparison.OrdinalIgnoreCase))
{
process.StartInfo.ArgumentList.Add("-c");
process.StartInfo.ArgumentList.Add(ArgumentBuilder.ConcatenateCommandAndArgArrayForPwshProcessStart(cmd, args));
}
else
{
process.StartInfo.ArgumentList.Add("-c");
Expand Down
23 changes: 23 additions & 0 deletions test/ArgumentBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,29 @@ public void EscapeAndConcatenateCommandAndArgArrayForProcessStart(string command
result.ShouldBe(expected);
}

[Theory]
[InlineData("pwsh", null, "pwsh")]
[InlineData("pws \"h\"", null, "pws \"h\"")]
[InlineData("p w s h", null, "p w s h")]
[InlineData("pwsh", new string[0], "pwsh")]
[InlineData("pwsh", new[] { "one", "two", "three" }, "pwsh one two three")]
[InlineData("pwsh", new[] { "line1\nline2", "word1\tword2" }, "pwsh line1\nline2 word1\tword2")]
[InlineData("pwsh", new[] { "with spaces" }, "pwsh with spaces")]
[InlineData("pwsh", new[] { @"with\backslash" }, @"pwsh with\backslash")]
[InlineData("pwsh", new[] { @"""quotedwith\backslash""" }, @"pwsh ""quotedwith\backslash""" )]
[InlineData("pwsh", new[] { @"C:\Users\" }, @"pwsh C:\Users\")]
[InlineData("pwsh", new[] { @"C:\Program Files\dotnet\" }, @"pwsh C:\Program Files\dotnet\")]
[InlineData("pwsh", new[] { @"backslash\""preceedingquote" }, @"pwsh backslash\""preceedingquote")]
[InlineData("pwsh", new[] { @""" hello """ }, @"pwsh "" hello """)]
public void ConcatenateCommandAndArgArrayForPwshProcessStart(string command, string[]? args, string expected)
{
// Given / When
var result = ArgumentBuilder.ConcatenateCommandAndArgArrayForPwshProcessStart(command, args);

// Then
result.ShouldBe(expected);
}

[Theory]
[InlineData("cmd", null, "cmd")]
[InlineData("cm \"d\"", null, "cm \"d\"")]
Expand Down