2016-02-25 2 views
0

У меня есть серия пакетных файлов, которые я хочу запустить с автоматическим вводом.Как определить, когда пакетный файл в другом процессе запрашивает ввод?

Все они имеют по крайней мере одну точку в своем исполнении, где они останавливаются и просят ввода. Либо через:

set /p FOO=Please enter value for FOO: 

или просто простой

pause 

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

Это избавляет от двух сценариев. Другой, однако, не имеет выхода до первого приглашения.

Я попытался использовать Process.WaitForInputIdle, но это вызывает исключение, поскольку в этом процессе нет цикла сообщений.

Мой код до сих пор:

private void Foo() 
     var p = StartElevatedProcess("script.bat", true /*redirect*/); 
     p.OutputDataReceived += p_OutputDataReceived; 
     p.BeginOutputReadLine(); 
     p.WaitForExit(); 
    } 

    void p_OutputDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     if (e.Data == null) return; 
     Console.WriteLine(e.Data); 

     if (e.Data.StartsWith("Install complete")) 
     { 
      ((Process)sender).StandardInput.WriteLine(); 
     } 
    } 
+0

Добавить предварительный запрос к третьему скрипту. – Kevin

+0

@Kevin: Я мог бы это сделать, но вся цель упражнения - не вручную обрабатывать эти файлы вручную. – Kempeth

+0

Просто случайная идея. Вы контролируете пакетный скрипт? Если это так, простой способ связи между потоком C# и интерпретатором cmd может заключаться в передаче данных в буфер обмена. Имейте пакетный скрипт '(echo prompt1) | клип', то есть C# do 'while (! System.Windows.Forms.ContainsText (" prompt1 ")) {System.Threading.Thread.Sleep (50)}' или подобное. – rojo

ответ

0

я, наконец, понял это. Асинхронный режим может не поддерживать это, но синхронное чтение в StandardOutput делает!

 Process p = StartElevatedProcess(
      "script.bat", 
      true); 
     do 
     { 
      char[] buff = new char[1000]; 
      int i = p.StandardOutput.Read(buff, 0, buff.Length); 
      string output = new String(buff, 0, i); 
      if (output.Contains("Please enter value for FOO:")) 
      { 
       Console.WriteLine(output); 
       p.StandardInput.WriteLine("Foo value"); 
      } 
      else if (output.Contains("Please enter value for BAR:")) 
      { 
       Console.WriteLine(output); 
       p.StandardInput.WriteLine("Bar value"); 
      } 
      else if (output.Contains(". . .")) 
      { 
       // Handle "Hit any key to continue" 
       p.StandardInput.WriteLine(); 
      } 
      else 
      { 
       Console.WriteLine(output); 
      } 
      Thread.Sleep(100); 
     } while (!p.HasExited); 

Возможно, это не идеальный вариант. Могут возникнуть проблемы с разрывом строк, создаваемых сценарием, который дает много результатов или работает очень долго. Но, надеюсь, это спасет кого-то еще, чтобы понять это.

Смежные вопросы