diff --git a/examples/ScratchPad.Fs.ArgumentPrinter/Program.fs b/examples/ScratchPad.Fs.ArgumentPrinter/Program.fs
new file mode 100644
index 0000000..d0b6b98
--- /dev/null
+++ b/examples/ScratchPad.Fs.ArgumentPrinter/Program.fs
@@ -0,0 +1,8 @@
+// For more information see https://aka.ms/fsharp-console-apps
+
+open System
+
+let args = Environment.GetCommandLineArgs()
+printfn "%i" args.Length
+for a in args do
+ printfn "%s" a
diff --git a/examples/ScratchPad.Fs.ArgumentPrinter/ScratchPad.Fs.ArgumentPrinter.fsproj b/examples/ScratchPad.Fs.ArgumentPrinter/ScratchPad.Fs.ArgumentPrinter.fsproj
new file mode 100644
index 0000000..5a150c1
--- /dev/null
+++ b/examples/ScratchPad.Fs.ArgumentPrinter/ScratchPad.Fs.ArgumentPrinter.fsproj
@@ -0,0 +1,13 @@
+
+
+
+ Exe
+ net8.0
+ false
+
+
+
+
+
+
+
diff --git a/examples/ScratchPad.Fs/Program.fs b/examples/ScratchPad.Fs/Program.fs
index aba6e22..f1556cf 100644
--- a/examples/ScratchPad.Fs/Program.fs
+++ b/examples/ScratchPad.Fs/Program.fs
@@ -54,5 +54,6 @@ exec { run "dotnet" args }
let _ = shell { exec "dotnet" args }
let statusCode = exec { exit_code_of "dotnet" "--help"}
+exec { run "dotnet" "run" "--project" "examples/ScratchPad.Fs.ArgumentPrinter" "--" "With Space" }
printfn "That's all folks!"
diff --git a/proc.sln b/proc.sln
index e34d5ec..6cfbde5 100644
--- a/proc.sln
+++ b/proc.sln
@@ -41,6 +41,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Proc.Fs", "src\Proc.Fs\Proc
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ScratchPad.Fs", "examples\ScratchPad.Fs\ScratchPad.Fs.fsproj", "{C33E3F7C-0C2A-4DD2-91E4-328866195997}"
EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ScratchPad.Fs.ArgumentPrinter", "examples\ScratchPad.Fs.ArgumentPrinter\ScratchPad.Fs.ArgumentPrinter.fsproj", "{50A40BEB-1C22-41CF-908F-F24FB34B1699}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -79,6 +81,10 @@ Global
{C33E3F7C-0C2A-4DD2-91E4-328866195997}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C33E3F7C-0C2A-4DD2-91E4-328866195997}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C33E3F7C-0C2A-4DD2-91E4-328866195997}.Release|Any CPU.Build.0 = Release|Any CPU
+ {50A40BEB-1C22-41CF-908F-F24FB34B1699}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {50A40BEB-1C22-41CF-908F-F24FB34B1699}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {50A40BEB-1C22-41CF-908F-F24FB34B1699}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {50A40BEB-1C22-41CF-908F-F24FB34B1699}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -92,5 +98,6 @@ Global
{D6997ADC-E933-418E-831C-DE1A78897493} = {E89606EC-111B-4151-997C-8006627F1926}
{5EA4E26F-F623-473D-9CD7-E590A3E54239} = {9C336E9A-3FC8-4F77-A5B4-1D07E4E54924}
{C33E3F7C-0C2A-4DD2-91E4-328866195997} = {E4B3DD3A-E36C-46D6-B35E-D824EB9B3C06}
+ {50A40BEB-1C22-41CF-908F-F24FB34B1699} = {E4B3DD3A-E36C-46D6-B35E-D824EB9B3C06}
EndGlobalSection
EndGlobal
diff --git a/src/Proc/Extensions/ArgumentExtensions.cs b/src/Proc/Extensions/ArgumentExtensions.cs
new file mode 100644
index 0000000..4a875e9
--- /dev/null
+++ b/src/Proc/Extensions/ArgumentExtensions.cs
@@ -0,0 +1,25 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ProcNet.Extensions;
+
+internal static class ArgumentExtensions
+{
+ public static string NaivelyQuoteArguments(this IEnumerable arguments)
+ {
+ if (arguments == null) return string.Empty;
+ var args = arguments.ToList();
+ if (args.Count == 0) return string.Empty;
+ var quotedArgs = args
+ .Select(a =>
+ {
+ if (!a.Contains(" ")) return a;
+ return $"\"{a}\"";
+ })
+ .ToList();
+ return string.Join(" ", quotedArgs);
+ }
+
+}
diff --git a/src/Proc/ObservableProcessBase.cs b/src/Proc/ObservableProcessBase.cs
index 27b64b7..1fea092 100644
--- a/src/Proc/ObservableProcessBase.cs
+++ b/src/Proc/ObservableProcessBase.cs
@@ -7,6 +7,7 @@
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
+using ProcNet.Extensions;
using ProcNet.Std;
namespace ProcNet
@@ -140,13 +141,19 @@ private Process CreateProcess()
var processStartInfo = new ProcessStartInfo
{
FileName = s.Binary,
- Arguments = args != null ? string.Join(" ", args) : string.Empty,
+ #if !NETSTANDARD2_1
+ Arguments = args.NaivelyQuoteArguments(),
+ #endif
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true
};
+ #if NETSTANDARD2_1
+ foreach (var arg in s.Args)
+ processStartInfo.ArgumentList.Add(arg);
+ #endif
if (s.Environment != null)
{
foreach (var kv in s.Environment)
diff --git a/src/Proc/Proc.Exec.cs b/src/Proc/Proc.Exec.cs
index b0e5057..3bef3ef 100644
--- a/src/Proc/Proc.Exec.cs
+++ b/src/Proc/Proc.Exec.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
+using ProcNet.Extensions;
namespace ProcNet
{
@@ -46,11 +47,18 @@ public static partial class Proc
/// The exit code of the binary being run
public static int? Exec(ExecArguments arguments, TimeSpan timeout)
{
- var args = string.Join(" ", arguments.Args ?? new string[]{});
- var info = new ProcessStartInfo(arguments.Binary, args)
+ var args = arguments.Args.NaivelyQuoteArguments();
+ var info = new ProcessStartInfo(arguments.Binary)
{
UseShellExecute = false
+ #if !NETSTANDARD2_1
+ , Arguments = args
+ #endif
};
+ #if NETSTANDARD2_1
+ foreach (var arg in arguments.Args)
+ info.ArgumentList.Add(arg);
+ #endif
var pwd = arguments.WorkingDirectory;
if (!string.IsNullOrWhiteSpace(pwd)) info.WorkingDirectory = pwd;
diff --git a/src/Proc/Proc.csproj b/src/Proc/Proc.csproj
index 5d4a66a..a3cc545 100644
--- a/src/Proc/Proc.csproj
+++ b/src/Proc/Proc.csproj
@@ -2,7 +2,7 @@
proc
- netstandard2.0;net461
+ netstandard2.0;netstandard2.1;net461
ProcNet