in src/Microsoft.Diagnostics.Runtime/src/Utilities/Command/Command.cs [109:194]
public Command(string commandLine, CommandOptions options)
{
Options = options;
_commandLine = commandLine;
// See if the command is quoted and match it in that case
Match m = Regex.Match(commandLine, "^\\s*\"(.*?)\"\\s*(.*)");
if (!m.Success)
m = Regex.Match(commandLine, @"\s*(\S*)\s*(.*)"); // thing before first space is command
ProcessStartInfo startInfo = new ProcessStartInfo(m.Groups[1].Value, m.Groups[2].Value)
{
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
ErrorDialog = false,
CreateNoWindow = true,
RedirectStandardInput = options.Input != null
};
Process = new Process { StartInfo = startInfo };
Process.StartInfo = startInfo;
_output = new StringBuilder();
if (options.elevate)
{
options.useShellExecute = true;
startInfo.Verb = "runas";
options.currentDirectory ??= Environment.CurrentDirectory;
}
Process.OutputDataReceived += OnProcessOutput;
Process.ErrorDataReceived += OnProcessOutput;
if (options.environmentVariables != null)
{
// copy over the environment variables to the process startInfo options.
foreach (KeyValuePair<string, string> pair in options.environmentVariables)
{
// look for %VAR% strings in the value and substitute the appropriate environment variable.
string value = pair.Value;
if (value != null)
{
value = Environment.ExpandEnvironmentVariables(value);
}
startInfo.EnvironmentVariables[pair.Key] = value;
}
}
startInfo.WorkingDirectory = options.currentDirectory ?? string.Empty;
_outputStream = options.outputStream;
if (options.outputFile != null)
{
_outputStream = File.CreateText(options.outputFile);
}
try
{
Process.Start();
}
catch (Exception e)
{
string msg = "Failure starting Process\r\n" +
" Exception: " + e.Message + "\r\n" +
" Cmd: " + commandLine + "\r\n";
if (Regex.IsMatch(startInfo.FileName, @"^(copy|dir|del|color|set|cd|cdir|md|mkdir|prompt|pushd|popd|start|assoc|ftype)", RegexOptions.IgnoreCase))
msg += " Cmd " + startInfo.FileName + " implemented by Cmd.exe, fix by prefixing with 'cmd /c'.";
throw new Exception(msg, e);
}
if (!startInfo.UseShellExecute)
{
// startInfo asynchronously collecting output
Process.BeginOutputReadLine();
Process.BeginErrorReadLine();
}
// Send any input to the command
if (options.input != null)
{
Process.StandardInput.Write(options.input);
Process.StandardInput.Dispose();
}
}