Перехват вывода консольной программы при непрямом запуске

Обсуждения по программированию для ОС Windows безотносительно используемого языка программирования. Windows NT, Win32, Windows API, ядро и драйверы.
Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Перехват вывода консольной программы при непрямом запуске

Сообщение Qwertiy » 14.04.2015 (Вт) 13:46

Есть bat-файл, который запускает другой bat-файл, который запускает приложение на java'е (tomkat). У него есть консольный вывод.
Как программно запустить эту цепочку, чтобы перехватить вывод tomkat'а?
Если запускать первый bat-файл при помощи cmd /k или cmd /c, то можно перехватить вывод двух bat-файлов.
Второй батник использует команду start для запуска. Пробовал менять на start /b, но всё равно появляется отдельное окно.
Желательно bat-файлы не менять, но если это необходимо, то возможно.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 14.04.2015 (Вт) 17:00

Qwertiy я не запускал TomKat приложения (они в виде war файлов ?),
но на примере запуска класса с помошью java можно соорудить нечто такое.
1.bat
Код: Выделить всё
2.bat

2.bat
Код: Выделить всё
javac Main.java
start "java Main > log.log"

Main.java
Код: Выделить всё
public class Main {
   public static void main(String... args) {
      System.out.println("Hello from Java!");
   }
}

Это если в файл нужно перенаправить.
Или интересует перенаправление в консоль откуда стартует 1.bat?

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.04.2015 (Вт) 17:13

Думаю, перенаправление в файл не подходит.

Интересует программный перехват вывода в то время, когда приложение запущено. Если ещё точнее, то требуется дождаться, когда оно выведет на консоль конкретную строку (ждать долго, от 1 до 10 минут).
Если я запускаю cmd, то я получаю весь вывод, который делается в эту консоль. Поэтому, если возможно принудительно направить вывод tomkat'а в ту же консоль, то это меня устраивает. Собственно, я на этот вариант и рассчитывал.
Если есть другой способ получения вывода в реальном времени, то он меня тоже устроит.
Если требуются не слишком длительные действия (в пределах минуты даже), за время которых вывод будет потерян, то этот вариант тоже устраивает.
Ждать завершения совсем не вариант, потому что его не планируется завершать. По крайней мере, другие действия должны выполняться когда он запущен.

Что касается перенаправления в файл и одновременного чтения этого файла - не уверен, не будет ли тут проблем, плюс, для того, чтобы это вообще работало требуется наличие вызовов flush томкатом, иначе нужный кусок может надолго остаться в буфере: интересует последняя строка вывода, после которой при отсутствии интерактивных действий с сайтом (которых не планируется) ничего не выводится. Или тут можно что-то сделать?

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 14.04.2015 (Вт) 17:18

Qwertiy так на вскидку сказать вожно ли так реализовать стандартным средствами Windows Batch не скажу.
Сделаю осторожное предположение что в PowerShell может получится, как не как через него доступны возможности .NET, но это если вариант перехода допускается.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.04.2015 (Вт) 17:27

Мне не требуется реализовывать на bat.
Т. е. я делаю программу на VB.NET, которая запускает bat, который по описанной выше схеме запускает tomkat. Мне в моей программе надо получить то, что tomkat выводит на консоль. Если бы он выводил в ту же консоль, у меня бы всё было. Но он выводит в свою. Вот до этого вывода надо как-то добраться.
Язык, на котором написана программа значения не имеет (в адекватных границах). Могу использовать Си++ или Node.js. Выбрал VB.NET, чтобы можно было адекватно отображать вывод (предполагается запуск нескольких программ, хотел разделить по вкладкам, поэтому не хотел использовать консольную программу). Но если требуются (да или просто удобны) какие-то фичи других языков, то без проблем можно их использовать.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 14.04.2015 (Вт) 17:38

Связка bat + tomkat константна? Если да, то напрямую (через VB.NET, C/C++, Node.js, прочее) tomkat запустить не разрешено условиями задачи?
Последний раз редактировалось Admiralisimys 15.04.2015 (Ср) 17:56, всего редактировалось 1 раз.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.04.2015 (Вт) 17:43

Формально, связка не константна, но разбираться, что делается в 300+ строках этих батников ни малейшего желания нет.
Можно как-то эмулировать исполнение bat-файла самому? Там преимущественно пляски вокруг переменных и каких-то файлов.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 14.04.2015 (Вт) 17:53

Qwertiy, а что если через SendMessage пулять в Java окно команды выделения строк и копирования последних, если за компом в это время не проводится активной работы, особенно с буфером обмена.
Средства вроде AutoIt позволяют и вовсе управлять персонажами в нескольких окнах какой-нибудь RPG, а тут всего лишь нужны информационные сообщения с консольного окна.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.04.2015 (Вт) 17:54

Хм.. Появилась одна идея.
В bat-файле вместо tomkat'а запустить (с ключом /b) некий прокси, который запустит томкат с перехватом его вывода и будет выводить всё на свою консоль.
Теоретически должно сработать, но что-то мне не нравится эта мысль.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.04.2015 (Вт) 17:56

Там нет графического окна, только консоль. Просто другая консоль. Вроде SendMessage тут не сработает?
И вообще, буфер бы трогать не хотелось. Идея в запуске набора шагов, каждый из которых может занимать от 2 до 10+ минут. Хотелось бы, чтобы компьютером в это время можно было спокойно пользоваться.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 14.04.2015 (Вт) 18:05

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

Что касается эмуляции выполнении bat файла, то в той же в консоли отладки IntelliJ IDEA реализована такая возможность. Так что да, с эмулировать выполнения батников можно.
Но со вложенным вызовом bat + java я не проверял.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.04.2015 (Вт) 18:12

Admiralisimys писал(а):В проксе нужно будет собрать все переменны окружения, включая те которые на создавали\на изменяли два батника, что по сути равноценно разберанию в их коде.

Разве вызываемый процесс их не унаследует сам?

Admiralisimys писал(а):Что касается эмуляции выполнении bat файла, то в той же в консоли отладки Idea реализована такая возможность.

Именно bat? Или просто командная строка?
В bat (как минимум) немного другой синтаксис переменных и есть предопределённые переменные.
Что касается передачи команды на исполнение, то в си есть функция system.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 14.04.2015 (Вт) 18:51

Qwertiy унаследует то унаследует, а сможет ли передать дальше - ведь вызов tomkat будет сводится не к простому запуску класса/пакета, а запуск очевидно с параметрами, некоторые из которых должны будут подставлены из окружения.

Там именно полноценный терминал cmd (View->Tool Windows->Terminal (Alt+F12)), так что всё что запускает cmd запустится и здесь.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.04.2015 (Вт) 18:54

Admiralisimys писал(а):а запуск очевидно с параметрами, некоторые из которых должны будут подставлены из окружения.

Но ведь cmd их уже раскроет, когда запустит моё приложение. А оно передаст все аргументы как есть.
Надо будет попробовать.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.04.2015 (Вт) 19:04

Admiralisimys писал(а):Там именно полноценный терминал cmd (View->Tool Windows->Terminal (Alt+F12)), так что всё что запускает cmd запустится и здесь.

Такой не проблема сделать - запускаем консоль, перехватываем вывод, показываем в своём окне. Ввод пересылаем в обратную сторону.

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 15.04.2015 (Ср) 17:44

требуется наличие вызовов flush томкатом

Если мы перенаправляем поток какая разница вызываемой программе, ведь она всё так же полагает что выводит в консоль разве нет*?

Есть такой PowerShell вариант
Применяя к теме, заменив ping на вызов 1.bat со второго поста.
0.ps1
Код: Выделить всё
$Process = New-Object system.Diagnostics.Process
$Process.StartInfo = New-Object System.Diagnostics.ProcessStartInfo(".\1.bat")

$Process.StartInfo.RedirectStandardOutput = $true
$Process.StartInfo.RedirectStandardError = $true

$Process.StartInfo.UseShellExecute = $false

$Process.Start() | Out-Null

echo "Live output..."

while (!$Process.HasExited){
   $line = $Process.StandardOutput.ReadLine()
   Write-Host $line
   $stdout += $line + "`n"
}

$line = $Process.StandardOutput.ReadToEnd()
Write-Host $line
$stdout += $line + "`n"

$stderr = $stderr + $Process.StandardError.ReadToEnd()

echo "Check the variable contains all output...`n"

Write-Host "stdout: $stdout"

Write-Host "stderr: $stderr"

В 2.bat start был изменён так
start /b java Main
ну, а для проверки Java прога была переписана
Main.java
Код: Выделить всё
import java.util.Timer;
import java.util.TimerTask;

public class Main {
   public static int much = 0;
   public static Timer timer = new Timer();
   public static void main(String... args) {
      System.out.println("Hello from Java!");
      timer.scheduleAtFixedRate(new TimerTask() {
         @Override
         public void run() {
            System.out.println("Tick " + much++);
            System.out.flush();
            if (much == 10) {
               timer.cancel();
            }
         }
      }, 0, 1000);
   }
}

System.out.flush() был добавлен сознательно, но предположения в цитате в данном примере с таймером не помогло (*отвечая на свой же заданный вопрос, оказывается разница есть, предположу что дело в нескольких потоках), такой интерактивности как с ping нет.
"Hello from Java!" выводится сразу, а вот 10 строк с Tick сразу после завершения выполнения. Так что для взаимодействия с tomkat может и не подойти, но требуется проверка на реальной программе.
Последний раз редактировалось Admiralisimys 15.04.2015 (Ср) 17:55, всего редактировалось 1 раз.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 15.04.2015 (Ср) 17:47

Admiralisimys писал(а):Если мы перенаправляем поток какая разница вызываемой программе, ведь она всё так же полагает что выводит в консоль разве нет*?

Вызываемой-то никакой. А вот той, которая попытается читать вывод из файла - будет, поскольку он будет появляться в файле не мгновенно, а только после вызова flush. Ну и stdout/stderr не будут синхронными.

Admiralisimys писал(а):start /b java Main

Я пробовал делать start /b, но всё равно появлялось новое окно - видимо, фича tomkat'а?

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 15.04.2015 (Ср) 17:53

Так, а через PowerShell скрипт выше тоже нечего не выводит в первой консоли?

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 15.04.2015 (Ср) 18:03

Не пробовал.
Так, он ещё и не установлен. Всё-таки установлен.
А что именно ты мне предлагаешь им запускать?

R тому же, не запускается:
Код: Выделить всё
File D:\.....................................\0.ps1 cannot be loaded because the execution of scripts is disabled on thi
s system. Please see "get-help about_signing" for more details.
At line:1 char:8
+ .\0.ps1 <<<<
    + CategoryInfo          : NotSpecified: (:) [], PSSecurityException
    + FullyQualifiedErrorId : RuntimeException

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 15.04.2015 (Ср) 18:10

Qwertiy нужно запустить сам PowerShell и выполнить команду Set-ExecutionPolicy RemoteSigned -scope CurrentUser, а свои текущие установки можно посмотреть через Get-ExecutionPolicy -list.
Более детальное описание по настройке прав можно узнать по предложенной команде
Qwertiy писал(а):
Код: Выделить всё
cannot be loaded because the execution of scripts is disabled on thi
s system. Please see "get-help about_signing" for more details.


А предлагаю я им запустить батники из темы, вместе с Java кодом. Но более практично будет заменить в PowerShell коде 1.bat на имя того батника который запускает батник который вызывает tomkat.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 15.04.2015 (Ср) 18:16

Ладно, а что ты мне предлагаешь этим скриптом запускать-то?

И чем он лучше этого?
Код: Выделить всё
  ChDir("D:\Некий Путь\tomcat-7 - R5\bin")
  Dim Info As New ProcessStartInfo With {.FileName = "cmd.exe", .Arguments = "/k ""D:\Некий Путь\tomcat-7 - R5\bin\startup.bat""", .RedirectStandardOutput = True, .RedirectStandardError = True, .UseShellExecute = False, .CreateNoWindow = True}
  Dim Prc As Process = Process.Start(Info)

  Do
    Dim Line As String = Await Prc.StandardOutput.ReadLineAsync()
    If Line Is Nothing Then Exit Do
    RtbStart1.Text += Line + vbCrLf
  Loop

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перехват вывода консольной программы при непрямом запуск

Сообщение Admiralisimys » 15.04.2015 (Ср) 18:51

Qwertiy да в общем-то ничем, кстати с предложенными в теме батниками и Джавой справился.
Код собран как консольное приложение и запускается с консоли?
Код: Выделить всё
Imports System
Imports System.Diagnostics
Imports System.Windows.Forms

Class BatRunner
   Inherits Form

   <STAThread()>
   Public Shared Sub Main()
      Application.Run(New BatRunner())
   End Sub

   Public Sub New()
      StartBat()
   End Sub

   Private Async Sub StartBat()
      Dim Info As New ProcessStartInfo With {.FileName = "cmd.exe", .Arguments = "/k ""1.bat""", .RedirectStandardOutput = True, .RedirectStandardError = True, .UseShellExecute = False, .CreateNoWindow = True}
      Dim Prc As Process = Process.Start(Info)

      Do
         Dim Line As String = Await Prc.StandardOutput.ReadLineAsync()
         If Line Is Nothing Then Exit Do
            System.Console.WriteLine(Line)
      Loop
   End Sub

End Class

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 15.04.2015 (Ср) 19:07

Qwertiy писал(а):Код собран как консольное приложение и запускается с консоли?

Нет, как WinForms. Но вывод от bat-файлов перехватывается нормально.


Вернуться в Windows-программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

    TopList