|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Cli.CommandFactory.CommandResolution;
public class WindowsExePreferredCommandSpecFactory : IPlatformCommandSpecFactory
{
public CommandSpec CreateCommandSpec(
string commandName,
IEnumerable<string> args,
string commandPath,
IEnvironmentProvider environment)
{
var useCmdWrapper = false;
if (Path.GetExtension(commandPath).Equals(".cmd", StringComparison.OrdinalIgnoreCase))
{
var preferredCommandPath = environment.GetCommandPath(commandName, ".exe");
if (preferredCommandPath == null)
{
useCmdWrapper = true;
}
else
{
commandPath = preferredCommandPath;
}
}
return useCmdWrapper
? CreateCommandSpecWrappedWithCmd(commandPath, args)
: CreateCommandSpecFromExecutable(commandPath, args);
}
private static CommandSpec CreateCommandSpecFromExecutable(
string command,
IEnumerable<string> args)
{
var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args);
return new CommandSpec(command, escapedArgs);
}
private static CommandSpec CreateCommandSpecWrappedWithCmd(
string command,
IEnumerable<string> args)
{
var comSpec = Environment.GetEnvironmentVariable("ComSpec") ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe");
// Handle the case where ComSpec is already the command
if (command.Equals(comSpec, StringComparison.OrdinalIgnoreCase))
{
command = args.FirstOrDefault();
args = args.Skip(1);
}
var cmdEscapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForCmdProcessStart(args);
if (!ArgumentEscaper.IsSurroundedWithQuotes(command) // Don't quote already quoted strings
&& ArgumentEscaper.ShouldSurroundWithQuotes(command))
{
command = $"\"{command}\"";
}
var escapedArgString = $"/s /c \"{command} {cmdEscapedArgs}\"";
return new CommandSpec(comSpec, escapedArgString);
}
}
|