Question

Je voudrais lancer un programme de ligne de commande externe à partir de mon application Mono / .NET. Par exemple, je voudrais courir MEncoder . Est-il possible:

  1. Pour obtenir la sortie de shell de ligne de commande, et d'écrire sur ma boîte de texte?
  2. Pour obtenir la valeur numérique pour afficher une barre de progression avec le temps écoulé?
Était-ce utile?

La solution

Lorsque vous créez votre objet Process ensemble StartInfo appropriée:

var proc = new Process 
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "program.exe",
        Arguments = "command line arguments to your executable",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    }
};

puis commencer le traitement et la lecture de celui-ci:

proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
    string line = proc.StandardOutput.ReadLine();
    // do something with line
}

Vous pouvez utiliser int.Parse() ou int.TryParse() pour convertir les chaînes en valeurs numériques. Vous pourriez avoir à faire une manipulation de chaînes d'abord s'il y a des caractères numériques non valides dans les chaînes que vous lisez.

Autres conseils

Vous pouvez traiter votre sortie synchroniquement ou de manière asynchrone .

1: exemple synchrone

static void runCommand()
{
    Process process = new Process();
    process.StartInfo.FileName = "cmd.exe";
    process.StartInfo.Arguments = "/c DIR"; // Note the /c command (*)
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    process.Start();
    //* Read the output (or the error)
    string output = process.StandardOutput.ReadToEnd();
    Console.WriteLine(output);
    string err = process.StandardError.ReadToEnd();
    Console.WriteLine(err);
    process.WaitForExit();
}

Remarque il est préférable de traiter à la fois sortie et erreurs : ils doivent être traités séparément

.

(*) Pour certaines commandes (ici StartInfo.Arguments), vous devez ajouter le /c directive , sinon le gel du processus dans la WaitForExit().

2: exemple Asynchronous

static void runCommand() 
{
    //* Create your Process
    Process process = new Process();
    process.StartInfo.FileName = "cmd.exe";
    process.StartInfo.Arguments = "/c DIR";
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    //* Set your output and error (asynchronous) handlers
    process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
    process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
    //* Start process and handlers
    process.Start();
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();
    process.WaitForExit();
}

static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) 
{
    //* Do your stuff with the output (write to console/log/StringBuilder)
    Console.WriteLine(outLine.Data);
}

Si vous n'avez pas besoin de faire des opérations avec la sortie compliquer, vous pouvez contourner la méthode OutputHandler, tout en ajoutant les gestionnaires directement en ligne:

//* Set your output and error (asynchronous) handlers
process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
process.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);

D'accord, pour tous ceux qui veulent les erreurs et les sorties lu, mais obtient Blocages avec l'une des solutions, à condition que dans d'autres réponses (comme moi), voici une solution que je construit après avoir lu l'explication MSDN de la propriété standardOutput.

Réponse est basée sur le code T30:

static void runCommand()
{
    //* Create your Process
    Process process = new Process();
    process.StartInfo.FileName = "cmd.exe";
    process.StartInfo.Arguments = "/c DIR";
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    //* Set ONLY ONE handler here.
    process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
    //* Start process
    process.Start();
    //* Read one element asynchronously
    process.BeginErrorReadLine();
    //* Read the other one synchronously
    string output = process.StandardOutput.ReadToEnd();
    Console.WriteLine(output);
    process.WaitForExit();
}

static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) 
{
    //* Do your stuff with the output (write to console/log/StringBuilder)
    Console.WriteLine(outLine.Data);
}
  1. Il est possible d'obtenir la sortie de shell de ligne de commande d'un procédé tel que décrit ici: http://www.c-sharpcorner.com/UploadFile/edwinlima/SystemDiagnosticProcess12052005035444AM/SystemDiagnosticProcess.aspx

  2. Cela dépend de mencoder. Si elle Ouputs ce statut sur la ligne de commande alors oui:)

vous pouvez utiliser la mémoire partagée pour les 2 processus de communiquer par le biais, consultez MemoryMappedFile

vous allez surtout créer une mémoire fichier mis en correspondance mmf dans le processus parent à l'aide « à l'aide » déclaration puis créer le deuxième processus jusqu'à ce qu'il se termine et le laisser écrire le résultat à l'mmf en utilisant BinaryWriter, puis lire le résultat de la mmf en utilisant le processus parent, vous pouvez également passer le nom de mmf en utilisant des arguments de ligne de commande ou le code dur il.

assurez-vous que lorsque vous utilisez le fichier mis en correspondance dans le processus parent que vous rendre le processus d'écriture enfant le résultat au fichier mappé avant que le fichier mappé est libéré dans le processus parent

Exemple: processus parent

    private static void Main(string[] args)
    {
        using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("memfile", 128))
        {
            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                BinaryWriter writer = new BinaryWriter(stream);
                writer.Write(512);
            }

            Console.WriteLine("Starting the child process");
            // Command line args are separated by a space
            Process p = Process.Start("ChildProcess.exe", "memfile");

            Console.WriteLine("Waiting child to die");

            p.WaitForExit();
            Console.WriteLine("Child died");

            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                BinaryReader reader = new BinaryReader(stream);
                Console.WriteLine("Result:" + reader.ReadInt32());
            }
        }
        Console.WriteLine("Press any key to continue...");
        Console.ReadKey();
    }

processus enfant

    private static void Main(string[] args)
    {
        Console.WriteLine("Child process started");
        string mmfName = args[0];

        using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(mmfName))
        {
            int readValue;
            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                BinaryReader reader = new BinaryReader(stream);
                Console.WriteLine("child reading: " + (readValue = reader.ReadInt32()));
            }
            using (MemoryMappedViewStream input = mmf.CreateViewStream())
            {
                BinaryWriter writer = new BinaryWriter(input);
                writer.Write(readValue * 2);
            }
        }

        Console.WriteLine("Press any key to continue...");
        Console.ReadKey();
    }

pour utiliser cet exemple, vous devrez créer une solution avec 2 projets à l'intérieur, vous prenez le résultat de la construction du processus d'enfant% childDir% / bin / debug et le copier% ParentDirectory% / bin / debug puis exécutez le projet parent

childDir et parentDirectory sont les noms de dossiers de vos projets sur le PC bonne chance:)

Comment lancer un processus (par exemple un fichier de chauve-souris, le script perl, programme de la console) et avoir sa sortie standard affichée sur une fenêtre de forme:

processCaller = new ProcessCaller(this);
//processCaller.FileName = @"..\..\hello.bat";
processCaller.FileName = @"commandline.exe";
processCaller.Arguments = "";
processCaller.StdErrReceived += new DataReceivedHandler(writeStreamInfo);
processCaller.StdOutReceived += new DataReceivedHandler(writeStreamInfo);
processCaller.Completed += new EventHandler(processCompletedOrCanceled);
processCaller.Cancelled += new EventHandler(processCompletedOrCanceled);
// processCaller.Failed += no event handler for this one, yet.

this.richTextBox1.Text = "Started function.  Please stand by.." + Environment.NewLine;

// the following function starts a process and returns immediately,
// thus allowing the form to stay responsive.
processCaller.Start();    

Vous pouvez trouver ProcessCaller sur ce lien: le lancement d'un processus et d'afficher sa sortie standard

La solution qui a fonctionné pour moi dans la victoire et Linux est le suivant

// 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 };
            }
        }

Vous pouvez vous connecter en utilisant la sortie de processus ci-dessous le code suivant:

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) { 
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top