Question

J'ai ce qui suit:

C:\temp\dowork.exe < input.txt
processing.......
complete
C:\

J'essaye ceci:

processArguments = " < input.txt";
pathToExe = "C:\\temp\dowork.exe";
startInfo = new ProcessStartInfo
                {
                     FileName = pathToExe,
                     UseShellExecute = false,
                     WorkingDirectory = FilepathHelper.GetFolderFromFullPath(pathToExe),
                     Arguments = processArguments
                };

try
 {
    using (_proc = Process.Start(startInfo))
     _proc.WaitForExit();
 }
catch (Exception e)
  {
    Console.WriteLine(e);
}

Et mon Dowork.exe s'écrase après le début () est appelé.

Aucune suggestion?

Publier la mise à jour de la question.

Merci à tous pour votre contribution. J'ai résolu le problème en utilisant la réponse d'Amit_G. Merci à Phil d'avoir montré probablement la meilleure façon (bien que je ne l'ai pas testé, je peux voir pourquoi c'est mieux). Vous trouverez ci-dessous ma solution complète. N'hésitez pas à copier et à modifier pour votre propre problème.

1) Créez un projet d'application de console, ajoutez cette classe

internal class DoWork
{
    private static void Main(string[] args)
    {
        var fs = new FileStream("C:\\temp\\output.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None);

        var toOutput = "Any items listed below this were passed in as args." + Environment.NewLine;
        foreach (var s in args)
            toOutput += s + Environment.NewLine;

        Console.WriteLine("I do work. Please type any letter then the enter key.");
        var letter = Console.ReadLine();
        Console.WriteLine("Thank you.");
        Thread.Sleep(500);

        toOutput += "Anything below this line should be a single letter." + Environment.NewLine;
        toOutput += letter + Environment.NewLine;

        var sw = new StreamWriter(fs);
        sw.Write(toOutput);

        sw.Close();
        fs.Close();
    }
}

2) Créer 1 fichier: c: temp input.txt

3) Modifier l'input.txt, tapez une seule lettre 'w' et enregistrez (c'est vrai que le fichier contient une seule lettre).

4) Créez un nouveau projet de bibliothèque de classe. Ajoutez une référence à Nunit (j'utilise la version 2.2).

5) Créez une classe TestFixture, elle devrait ressembler à ce qui suit. Remarque: Ce luminaire de test est de gérer les ressources externes, en tant que telle, vous ne pouvez pas exécuter l'intégralité du luminaire, plutôt exécuter chaque test une seule à-une. Vous pouvez résoudre ce problème en vous assurant que tous les flux de fichiers sont fermés, mais je ne me souciais pas d'écrire ceci, n'hésitez pas à l'étendre vous-même.

using System.Diagnostics;
using System.IO;
using NUnit.Framework;

namespace Sandbox.ConsoleApplication
{
[TestFixture]
public class DoWorkTestFixture
{
    // NOTE: following url explains how ms-dos performs redirection from the command line:
    // http://www.febooti.com/products/command-line-email/batch-files/ms-dos-command-redirection.html

    private string _workFolder = "C:\\Temp\\";
    private string _inputFile = "input.txt";
    private string _outputFile = "output.txt";
    private string _exe = "dowork.exe";

    [TearDown]
    public void TearDown()
    {
        File.Delete(_workFolder + _outputFile);
    }

    [Test]
    public void DoWorkWithoutRedirection()
    {
        var startInfo = new ProcessStartInfo
                            {
                                FileName = _workFolder + _exe,
                                UseShellExecute = false,
                                WorkingDirectory = _workFolder
                            };

        var process = Process.Start(startInfo);
        process.WaitForExit();

        Assert.IsTrue(File.Exists(_workFolder + _outputFile));
    }

    [Test]
    public void DoWorkWithoutRedirectionWithArgument()
    {
        var startInfo = new ProcessStartInfo
                            {
                                FileName = _workFolder + _exe,
                                UseShellExecute = false,
                                WorkingDirectory = _workFolder,
                                Arguments = _inputFile
                            };

        var process = Process.Start(startInfo);
        process.WaitForExit();

        var outputStrings = File.ReadAllLines(_workFolder + _outputFile);

        Assert.IsTrue(File.Exists(_workFolder + _outputFile));
        Assert.AreEqual(_inputFile, outputStrings[1]);
    }

    [Test]
    public void DoWorkWithRedirection()
    {
        var startInfo = new ProcessStartInfo
                            {
                                FileName = _workFolder + _exe,
                                UseShellExecute = false,
                                WorkingDirectory = _workFolder,
                                RedirectStandardInput = true
                            };

        var myProcess = Process.Start(startInfo);
        var myStreamWriter = myProcess.StandardInput;
        var inputText = File.ReadAllText(_workFolder + _inputFile);

        myStreamWriter.Write(inputText);

        // this is usually needed, not for this easy test though:
        // myProcess.WaitForExit();

        var outputStrings = File.ReadAllLines(_workFolder + _outputFile);

        Assert.IsTrue(File.Exists(_workFolder + _outputFile));
        // input.txt contains a single letter: 'w', it will appear on line 3 of output.txt
        if(outputStrings.Length >= 3)  Assert.AreEqual("w", outputStrings[2]);
    }

    [Test]
    public void DoWorkWithRedirectionAndArgument()
    {
        var startInfo = new ProcessStartInfo
        {
            FileName = _workFolder + _exe,
            UseShellExecute = false,
            WorkingDirectory = _workFolder,
            RedirectStandardInput = true
        };

        var myProcess = Process.Start(startInfo);
        var myStreamWriter = myProcess.StandardInput;
        var inputText = File.ReadAllText(_workFolder + _inputFile);

        myStreamWriter.Write(inputText);
        myStreamWriter.Close();

        // this is usually needed, not for this easy test though:
        // myProcess.WaitForExit();

        var outputStrings = File.ReadAllLines(_workFolder + _outputFile);

        Assert.IsTrue(File.Exists(_workFolder + _outputFile));
        // input.txt contains a single letter: 'w', it will appear on line 3 of output.txt
        Assert.IsTrue(outputStrings.Length >= 3);
        Assert.AreEqual("w", outputStrings[2]);
    }


}

}

Était-ce utile?

La solution

Vous devez utiliser la redirection STDIN. Comme ça...

inputFilePath = "C:\\temp\input.txt";
pathToExe = "C:\\temp\dowork.exe";

startInfo = new ProcessStartInfo
                {
                     FileName = pathToExe,
                     UseShellExecute = false,
                     WorkingDirectory = FilepathHelper.GetFolderFromFullPath(pathToExe),
                     RedirectStandardInput = true
                };

try
{
    using (_proc = Process.Start(startInfo))
    {
        StreamWriter myStreamWriter = myProcess.StandardInput;

        // Use only if the file is very small. Use stream copy (see Phil's comment).
        String inputText = File.ReadAllText(inputFilePath);

        myStreamWriter.Write(inputText);
    }

    _proc.WaitForExit();
}
catch (Exception e)
{
    Console.WriteLine(e);
}

Autres conseils

Tu vas vouloir faire quelque chose comme,

ProcessStartInfo startInfo = new ProcessStartInfo
{
    FileName = pathToExe,
    UseShellExecute = false,
    WorkingDirectory = FilepathHelper.GetFolderFromFullPath(pathToExe)
}; 


Process process = Process.Start(startInfo);
FileStream reader = File.OpenRead("input.txt");
reader.CopyTo(process.StandardInput.BaseStream);

Cela peut être fait, du moins d'une manière quelque peu "piratée" en passant des arguments directement à CMD.exe. Cependant, comme Je recommande d'émuler Le "<" manuellement comme dans les autres réponses, c'est ici comme une note seulement.

(foo.txt est contient deux lignes, "B" et "A", de sorte qu'ils seront inversés lorsqu'ils sont correctement triés)

var x = new ProcessStartInfo {
    FileName = "cmd",
    Arguments = "/k sort < foo.txt",
    UseShellExecute = false,
};
Process.Start(x);

Vous pouvez remplacer /k avec /c pour prévenir cmd.exe de rester ouvert. (Voir cmd /? pour les options).

Codage heureux.

Tout d'abord, vous n'avez pas besoin d'un espace précédant vos args. La méthode le fait pour vous. Cela pourrait vous gâcher pour commencer. Ce serait donc:

processArguments = "< input.txt";

Mais si cela ne fonctionne pas, vous pouvez essayer ::

process = "cmd.exe";
processArguments = "/c dowork.exe < input.txt";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top