我想从我的Mono/运行一个外部命令行程序。网络应用程序。 例如,我想运行mencoder。有没有可能:

获得命令行shell输出,并将其写在我的文本框? 获取数值以显示随着时间流逝的进度条?


当前回答

process不是最令人愉快的工作方式,因此您可能想尝试CliWrap。它为处理输出提供了许多不同的模型,包括管道、缓冲和实时流。下面是一些例子(摘自自述)。

简单地启动一个命令行可执行文件:

using CliWrap;

var result = await Cli.Wrap("path/to/exe")
    .WithArguments("--foo bar")
    .WithWorkingDirectory("work/dir/path")
    .ExecuteAsync();
    
// Result contains:
// -- result.ExitCode        (int)
// -- result.StartTime       (DateTimeOffset)
// -- result.ExitTime        (DateTimeOffset)
// -- result.RunTime         (TimeSpan)

启动一个命令行可执行文件,并在内存中缓冲stdout/stderr:

using CliWrap;
using CliWrap.Buffered;

// Calling `ExecuteBufferedAsync()` instead of `ExecuteAsync()`
// implicitly configures pipes that write to in-memory buffers.
var result = await Cli.Wrap("path/to/exe")
    .WithArguments("--foo bar")
    .WithWorkingDirectory("work/dir/path")
    .ExecuteBufferedAsync();

// Result contains:
// -- result.StandardOutput  (string)
// -- result.StandardError   (string)
// -- result.ExitCode        (int)
// -- result.StartTime       (DateTimeOffset)
// -- result.ExitTime        (DateTimeOffset)
// -- result.RunTime         (TimeSpan)

使用手动管道配置启动命令行可执行文件:

using CliWrap

var buffer = new StringBuilder();

var result = await Cli.Wrap("foo")
    .WithStandardOutputPipe(PipeTarget.ToFile("output.txt"))
    .WithStandardErrorPipe(PipeTarget.ToStringBuilder(buffer))
    .ExecuteAsync();

作为事件流启动命令行可执行文件:

using CliWrap;
using CliWrap.EventStream;

var cmd = Cli.Wrap("foo").WithArguments("bar");

await foreach (var cmdEvent in cmd.ListenAsync())
{
    switch (cmdEvent)
    {
        case StartedCommandEvent started:
            _output.WriteLine($"Process started; ID: {started.ProcessId}");
            break;
        case StandardOutputCommandEvent stdOut:
            _output.WriteLine($"Out> {stdOut.Text}");
            break;
        case StandardErrorCommandEvent stdErr:
            _output.WriteLine($"Err> {stdErr.Text}");
            break;
        case ExitedCommandEvent exited:
            _output.WriteLine($"Process exited; Code: {exited.ExitCode}");
            break;
    }
}

其他回答

标准的。net方法是从Process的StandardOutput流中读取数据。在链接的MSDN文档中有一个例子。类似地,您可以从standardror读取,并写入StandardInput。

您可以使用以下代码记录流程输出:

ProcessStartInfo pinfo = new ProcessStartInfo(item);
pinfo.CreateNoWindow = false;
pinfo.UseShellExecute = true;
pinfo.RedirectStandardOutput = true;
pinfo.RedirectStandardInput = true;
pinfo.RedirectStandardError = true;
pinfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
var p = Process.Start(pinfo);
p.WaitForExit();
Process process = Process.Start(new ProcessStartInfo((item + '>' + item + ".txt"))
{
    UseShellExecute = false,
    RedirectStandardOutput = true
});
process.WaitForExit();
string output = process.StandardOutput.ReadToEnd();
if (process.ExitCode != 0) { 
}

在win和linux中为我工作的解决方案如下

// GET api/values
        [HttpGet("cifrado/{xml}")]
        public ActionResult<IEnumerable<string>> Cifrado(String xml)
        {
            String nombreXML = DateTime.Now.ToString("ddMMyyyyhhmmss").ToString();
            String archivo = "/app/files/"+nombreXML + ".XML";
            String comando = " --armor --recipient bibankingprd@bi.com.gt  --encrypt " + archivo;
            try{
                System.IO.File.WriteAllText(archivo, xml);                
                //String comando = "C:\\GnuPG\\bin\\gpg.exe --recipient licorera@local.com --armor --encrypt C:\\Users\\Administrador\\Documents\\pruebas\\nuevo.xml ";
                ProcessStartInfo startInfo = new ProcessStartInfo() {FileName = "/usr/bin/gpg",  Arguments = comando }; 
                Process proc = new Process() { StartInfo = startInfo, };
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.RedirectStandardError = true;
                proc.Start();
                proc.WaitForExit();
                Console.WriteLine(proc.StandardOutput.ReadToEnd());
                return new string[] { "Archivo encriptado", archivo + " - "+ comando};
            }catch (Exception exception){
                return new string[] { archivo, "exception: "+exception.ToString() + " - "+ comando };
            }
        }

可以获得一个进程的命令行shell输出,如下所示:http://www.c-sharpcorner.com/UploadFile/edwinlima/SystemDiagnosticProcess12052005035444AM/SystemDiagnosticProcess.aspx 这取决于mencoder。如果它在命令行输出这个状态,那么是:)

process不是最令人愉快的工作方式,因此您可能想尝试CliWrap。它为处理输出提供了许多不同的模型,包括管道、缓冲和实时流。下面是一些例子(摘自自述)。

简单地启动一个命令行可执行文件:

using CliWrap;

var result = await Cli.Wrap("path/to/exe")
    .WithArguments("--foo bar")
    .WithWorkingDirectory("work/dir/path")
    .ExecuteAsync();
    
// Result contains:
// -- result.ExitCode        (int)
// -- result.StartTime       (DateTimeOffset)
// -- result.ExitTime        (DateTimeOffset)
// -- result.RunTime         (TimeSpan)

启动一个命令行可执行文件,并在内存中缓冲stdout/stderr:

using CliWrap;
using CliWrap.Buffered;

// Calling `ExecuteBufferedAsync()` instead of `ExecuteAsync()`
// implicitly configures pipes that write to in-memory buffers.
var result = await Cli.Wrap("path/to/exe")
    .WithArguments("--foo bar")
    .WithWorkingDirectory("work/dir/path")
    .ExecuteBufferedAsync();

// Result contains:
// -- result.StandardOutput  (string)
// -- result.StandardError   (string)
// -- result.ExitCode        (int)
// -- result.StartTime       (DateTimeOffset)
// -- result.ExitTime        (DateTimeOffset)
// -- result.RunTime         (TimeSpan)

使用手动管道配置启动命令行可执行文件:

using CliWrap

var buffer = new StringBuilder();

var result = await Cli.Wrap("foo")
    .WithStandardOutputPipe(PipeTarget.ToFile("output.txt"))
    .WithStandardErrorPipe(PipeTarget.ToStringBuilder(buffer))
    .ExecuteAsync();

作为事件流启动命令行可执行文件:

using CliWrap;
using CliWrap.EventStream;

var cmd = Cli.Wrap("foo").WithArguments("bar");

await foreach (var cmdEvent in cmd.ListenAsync())
{
    switch (cmdEvent)
    {
        case StartedCommandEvent started:
            _output.WriteLine($"Process started; ID: {started.ProcessId}");
            break;
        case StandardOutputCommandEvent stdOut:
            _output.WriteLine($"Out> {stdOut.Text}");
            break;
        case StandardErrorCommandEvent stdErr:
            _output.WriteLine($"Err> {stdErr.Text}");
            break;
        case ExitedCommandEvent exited:
            _output.WriteLine($"Process exited; Code: {exited.ExitCode}");
            break;
    }
}