Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

run bash command from .NetCore with arguments

I am trying to run one .NetCore program from another.

        ProcessStartInfo psi = new ProcessStartInfo();
        psi.FileName = "sh";
        psi.Arguments = "-c dotnet /home/myuser/PublishOutput/myprogram.dll";
        psi.UseShellExecute = false;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        Process proc = new Process
        {
            StartInfo = psi
        };


        proc.Start();

        string error = proc.StandardError.ReadToEnd();

        if (!string.IsNullOrEmpty(error))
            return "error: " + error;

        string output = proc.StandardOutput.ReadToEnd();

        proc.WaitForExit();

        return output;

As output I get:

Microsoft .NET Core Shared Framework Host

Version : 1.1.0 Build : 928f77c4bc3f49d892459992fb6e1d5542cb5e86

Usage: dotnet [common-options] [[options] path-to-application]

Common Options: --help Display .NET Core Shared Framework Host help. --version Display .NET Core Shared Framework Host version.

Options: --fx-version Version of the installed Shared Framework to use to run the application.
--additionalprobingpath Path containing probing policy and assemblies to probe for.

Path to Application: The path to a .NET Core managed application, dll or exe file to execute.

If you are debugging the Shared Framework Host, set 'COREHOST_TRACE' to '1' in your environment.

To get started on developing applications for .NET Core, install the SDK from: http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409

So I seems exacly like run command dotnet with no dll path argument.

like image 592
holocen Avatar asked Jul 02 '17 19:07

holocen


3 Answers

You need to escape the argument to -c so that it is one single argument:

psi.Arguments = "-c \"dotnet /home/myuser/PublishOutput/myprogram.dll\"";
like image 171
Martin Ullrich Avatar answered Nov 15 '22 22:11

Martin Ullrich


i change something and make the message can be output sync

using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace ExecuteCommandX
{
 /// <summary>
///  sample by [email protected]
/// </summary>
/// <param name="args"></param>
internal static class Program
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="args"></param>
    // ReSharper disable once UnusedParameter.Local
    private static void Main(string[] args)
    {
        var psi = new ProcessStartInfo
        {
            FileName = "ping",
            Arguments = "-c 3 8.8.8.8",
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        };

        var proc = new Process
        {
            StartInfo = psi
        };

        proc.Start();



        Task.WaitAll(Task.Run(() =>
        {
            while (!proc.StandardOutput.EndOfStream)
            {
                var line = proc.StandardOutput.ReadLine();
                Console.WriteLine(line);
            }
        }), Task.Run(() =>
        {
            while (!proc.StandardError.EndOfStream)
            {
                var line = proc.StandardError.ReadLine();
                Console.WriteLine(line);
            }
        }));


        proc.WaitForExit();
        Console.WriteLine(proc.ExitCode);
    }
}

}

like image 39
Linkanyway Avatar answered Nov 15 '22 22:11

Linkanyway


If you want to run a Linux program with specific commands (e.g. find / -name image.png) from your c# .net core application, you can use the following snippet:

            try
            {
                var process = new Process();
                var processStartInfo = new ProcessStartInfo()
                {
                    WindowStyle = ProcessWindowStyle.Hidden,
                    FileName = $"/bin/bash",
                    WorkingDirectory = workingDirectory = "/mnt",
                    Arguments = $"-c \"find / -name image.png\"",
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false
                };
                process.StartInfo = processStartInfo;
                process.Start();

                String error = process.StandardError.ReadToEnd();
                String output = process.StandardOutput.ReadToEnd();

            }
            catch(Exception ex)
            {
                //_logger.LogError(ex.Message, ex);
                throw;
            }

Notes on the arguments:

  • FileName = $"/bin/bash" for all shell commands you might use that
  • WorkingDirectory = workingDirectory = "/mnt" just an example, this directory is important if the command you're running needs files (e.g. file.png) it will than look relative to the working directory to fetch the file
  • Arguments = $"-c "find / -name image.png"" runs the following command in cli: /bin/bash -c "find / -name image.png"

-c is mandatory for it to work, as written in manpage:

-c string
If the -c option is present, then commands are read from string. If there are arguments >after the string, they are assigned to the positional parameters, starting with $0.

like image 2
jmahlitz Avatar answered Nov 15 '22 22:11

jmahlitz