| File: CommandFactory.cs | Web Access |
| Project: src\arcade\src\Common\Microsoft.Arcade.Common\Microsoft.Arcade.Common.csproj (Microsoft.Arcade.Common) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; namespace Microsoft.Arcade.Common { public class CommandFactory : ICommandFactory { public ICommand Create(string executable, params string[] args) { return Create(executable, ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args)); } public ICommand Create(string executable, IEnumerable<string> args) { return Create(executable, ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args)); } public ICommand Create(string executable, string args) { ResolveExecutablePath(ref executable, ref args); return new Command(executable, args); } private static void ResolveExecutablePath(ref string executable, ref string args) { // On Windows, we want to avoid using "cmd" if possible (it mangles the colors, and a bunch of other things) // So, do a quick path search to see if we can just directly invoke it var useCmd = ShouldUseCmd(executable); if (useCmd) { var comSpec = System.Environment.GetEnvironmentVariable("ComSpec"); // cmd doesn't like "foo.exe ", so we need to ensure that if // args is empty, we just run "foo.exe" if (!string.IsNullOrEmpty(args)) { executable = (executable + " " + args).Replace("\"", "\\\""); } args = $"/C \"{executable}\""; executable = comSpec; } } private static bool ShouldUseCmd(string executable) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { var extension = Path.GetExtension(executable); if (!string.IsNullOrEmpty(extension)) { return !string.Equals(extension, ".exe", StringComparison.Ordinal); } else if (executable.Contains(Path.DirectorySeparatorChar)) { // It's a relative path without an extension if (File.Exists(executable + ".exe")) { // It refers to an exe! return false; } } else { // Search the path to see if we can find it foreach (var path in System.Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator)) { var candidate = Path.Combine(path, executable + ".exe"); if (File.Exists(candidate)) { // We found an exe! return false; } } } // It's a non-exe :( return true; } // Non-windows never uses cmd return false; } } }