6

In my .NET Core Console app, I receive multiple commands in form of an array of string, and would like to execute them as console command (and showing their output in my own app if possible but not hard requirement).

At first, I tried to parse each command to separate their name and arguments and put them in ProcessStartInfo. However, some command does not work (even simple commands like echo "Hello").

Now I switched to call Powershell instead like this:

    static IEnumerable<ProcessStartInfo> ParseCommands(string[] args)
    {
        return args
            .Skip(1)
            .Select(q => new ProcessStartInfo()
            {
                FileName = "powershell",
                Arguments = q,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
            }).ToList();
    }

    static void RunCommand(ProcessStartInfo processInfo)
    {
        Console.WriteLine($"{processInfo.Arguments}");

        var process = new Process()
        {
            StartInfo = processInfo,
        };
        process.Start();

        while (!process.StandardOutput.EndOfStream)
        {
            Console.WriteLine(process.StandardOutput.ReadLine());
        }

        process.WaitForExit();
    }

The problem is I don't think this one can run on Linux or MacOS. Is there any "standard" way to tell my app to "run this as if it's a console command"?


This is my current code by using the Platform to determine the console command, feel free to tell me if there is a better way:

    static IEnumerable<ProcessStartInfo> ParseCommands(string[] args)
    {
        var argsPrepend = "";
        var shellName = "/bin/bash";
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            shellName = "cmd";
            argsPrepend = "/c ";
        }

        return args
            .Skip(1)
            .Select(q => new ProcessStartInfo()
            {
                FileName = shellName,
                Arguments = argsPrepend + q,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
            }).ToList();
    }

    static void RunCommand(ProcessStartInfo processInfo)
    {
        Console.WriteLine($"{processInfo.Arguments.Substring(processInfo.FileName == "cmd" ? 3 : 0)}");

        var process = new Process()
        {
            StartInfo = processInfo,
        };
        process.Start();

        while (!process.StandardOutput.EndOfStream)
        {
            Console.WriteLine(process.StandardOutput.ReadLine());
        }

        process.WaitForExit();
    }
Luke Vo
  • 17,859
  • 21
  • 105
  • 181
  • 1
    You can do the same with linux as well, according to this [C# execute a terminal command in linux](https://stackoverflow.com/questions/23679283/c-sharp-execute-a-terminal-command-in-linux) thread. Running a process is a standard way here – Pavel Anikhouski Apr 04 '20 at 14:04
  • Sorry for my illiteracy of Linux and MacOS, I didn't know what is used there. So, a solution now is check the Platform, use `powershell` if it's Windows and `/bin/bash` if it's Linux right? When asking this question I actually expected a solution without OS check, but it can be solved this way too, please post it as an answer. – Luke Vo Apr 04 '20 at 14:06
  • 1
    You can use `cmd` on windows, powershell can be disabled in some cases. The mentioned thread already has an answer, you can close your question as duplicate:) Or be more precise and include a commands, which you would like on different platforms – Pavel Anikhouski Apr 04 '20 at 14:07
  • The problem with cmd is that it prints out the headers too (Microsoft Windows blah blah blah version etc) – Luke Vo Apr 04 '20 at 14:09
  • 1
    You should use `cmd` with `/c` parameter, as it shown here [Run Command Prompt Commands](https://stackoverflow.com/questions/1469764/run-command-prompt-commands) – Pavel Anikhouski Apr 04 '20 at 14:11
  • 1
    Also as a note: remember you don’t need to run shell to run executables. Not sure if that’s the idea here or not, but I see so many people doing “cmd /c someprogram.exe” without any reason that it needs to be mentioned. – Sami Kuhmonen Apr 04 '20 at 14:24

0 Answers0