Configuring the process

edit

Arguments

WithArguments replaces the arguments with the ones you pass, as a list, a span or any IEnumerable<string>. Each string is one argument: spaces, quotes and backslashes reach the process as you wrote them, on every operating system. You never build a command line yourself.

ToString returns the command line, with the arguments quoted when they need it, for logs and error messages:

var command = ProcessWrapper.Create("dotnet")
    .WithArguments("build", "My Project.csproj");

// The command line, with the arguments quoted when needed
Assert.Equal(@"dotnet build ""My Project.csproj""", command.ToString());

Working directory

await ProcessWrapper.Create("git")
    .WithArguments("status")
    .WithWorkingDirectory("/path/to/repo")
    .ExecuteAsync();

The executable is looked up in the directories of PATH, not in the working directory, so a file in the working directory cannot replace the command PATH finds for the same name. Windows usually searches the current directory first; ProcessWrapper does not, on any operating system. When the working directory is trusted and the executable lives there, opt in with WithSearchWorkingDirectory:

await ProcessWrapper.Create("run.sh")
    .WithWorkingDirectory("/path/to/scripts")
    .WithSearchWorkingDirectory()
    .ExecuteAsync();

Environment variables

The process inherits the environment variables of the current process. Change them with a callback or a dictionary:

// Using callback
await ProcessWrapper.Create("my-app")
    .WithEnvironmentVariables(env => env
        .Set("MY_VAR", "value")
        .Remove("UNWANTED_VAR"))
    .ExecuteAsync();

// Using dictionary (null removes the variable)
await ProcessWrapper.Create("my-app")
    .WithEnvironmentVariables(new Dictionary<string, string?>
    {
        ["MY_VAR"] = "value",
        ["UNWANTED_VAR"] = null,
    })
    .ExecuteAsync();
  • Set adds or replaces a variable, and Remove removes it. In the dictionary, a null value removes the variable.
  • Successive calls accumulate: each one changes the variables left by the previous ones.

Windows credentials

On Windows, WithCredentials(userName, password, domain) starts the process as another user. The password is a string or a SecureString, and the user name can be in the user@domain format when you do not pass a domain. WithUseCredentialsForNetworkingOnly uses the credentials for network access only, like runas /netonly.

Options of .NET 11

When the application targets .NET 11, more options are available:

MethodEffectPlatforms
WithKillOnParentExitKills the process when the current process exitsWindows, Linux, Android
WithStartDetachedDetaches the process from the current processAll
WithStartSuspendedStarts the process suspendedWindows, macOS
StartAndForgetStarts the process without tracking it and returns its idAll but iOS and tvOS

StartAndForget throws an InvalidOperationException when the command has output targets, an input source or resource limits: nothing would read or apply them once the process is started.