Лучший способ взаимодействия с приложением командной строки - PullRequest
6 голосов
/ 14 января 2009

Мне нужно написать компонент для приложения, которое тесно взаимодействует с приложением командной строки. Приложение командной строки задает ряд вопросов, выполняет некоторые вычисления, а затем завершает работу (что мне нужно обнаружить). По сути, я хочу заключить это взаимодействие в класс-оболочку.

Кто-нибудь достиг подобного в прошлом? Если да, то как ты это сделал? Вы заметили шаблон или, может быть, какую-то хорошую сборку классов для использования? Ура!

Ответы [ 3 ]

15 голосов
/ 14 января 2009

Вам необходимо перенаправить как входной, так и выходной потоки, используя Process; это немного сложнее в обработке обоих, так как вы должны быть осторожны, чтобы в буферах ничего не потерялось (вызывая тупик).

Возможно, вы также захотите посмотреть OutputDataReceived для ответов на основе событий.

1 голос
/ 14 января 2009

Если все приложения разработаны в dotnet, вы можете использовать Класс сборки

0 голосов
/ 15 января 2019

Меня раздражают, когда мои ответы - это просто ссылки на другие сайты. Я не вижу, где ссылка на статью C # Corner очень помогает.

Вопросу сегодня 10 лет, но его следовало уточнить. Вопрос не указывает, есть ли в конце каждого вопроса окончания строк (CrLf). Предполагая, что есть, как в следующем:

string Answer;
Console.Out.WriteLine("First question: ");
Answer = Console.In.ReadLine();
Console.Out.WriteLine("Another question: ");
Answer = Console.In.ReadLine();
Console.Out.WriteLine("Final question: ");
Answer = Console.In.ReadLine();

Тогда для ответа можно использовать следующее:

class Program
{
    const string FirstQuestion = "First question: ";
    const string SecondQuestion = "Another question: ";
    const string FinalQuestion = "Final question: ";
    static AutoResetEvent Done = new AutoResetEvent(false);

    static void Main(string[] args)
    {
        const string TheProgram = @" ... ";
        Process p = new Process();
        ProcessStartInfo psi = new ProcessStartInfo(TheProgram);
        psi.UseShellExecute = false;
        psi.CreateNoWindow = true;
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;
        p.StartInfo = psi;
        Console.WriteLine("Executing " + TheProgram);
        p.Start();
        DoPromptsAsync(p);
        Done.WaitOne();
    }

    private static async Task DoPromptsAsync(Process p)
    {
        StreamWriter sw = p.StandardInput;
        StreamReader sr = p.StandardOutput;
        string Question;
        Question = await sr.ReadLineAsync();
        if (Question != FirstQuestion)
            return;
        sw.WriteLine("First answer");
        Console.WriteLine(Question + "answered");
        Question = await sr.ReadLineAsync();
        if (Question != SecondQuestion)
            return;
        sw.WriteLine("Second answer");
        Console.WriteLine(Question + "answered");
        Question = await sr.ReadLineAsync();
        if (Question != FinalQuestion)
            return;
        sw.WriteLine("Final answer");
        Console.WriteLine(Question + "answered");
        Done.Set();
    }
}

Следующее работает в приложении WPF; Для тестирования я использовал событие двойного щелчка, но его можно использовать в других событиях WPF.

const string TheProgram = @" ... ";
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo(TheProgram);
psi.UseShellExecute = false;
//psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
p.StartInfo = psi;
p.Start();
const string FirstQuestion = "First question: ";
const string SecondQuestion = "Another question: ";
const string FinalQuestion = "Final question: ";
StreamWriter sw = p.StandardInput;
StreamReader sr = p.StandardOutput;
string Question;
StringBuilder sb = new StringBuilder("Executing " + TheProgram + "\r\n");
Question = await sr.ReadLineAsync();
if (Question != FirstQuestion)
    return;
sw.WriteLine("First answer");
sb.Append(Question + "answered\r\n");
Question = await sr.ReadLineAsync();
if (Question != SecondQuestion)
    return;
sw.WriteLine("Second answer");
sb.Append(Question + "answered\r\n");
Question = await sr.ReadLineAsync();
if (Question != FinalQuestion)
    return;
sw.WriteLine("Final answer");
sb.Append(Question + "answered\r\n");
ResultBox.Text = sb.ToString();

Думаю, будет сложнее, если после каждого вопроса не будет конца строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...