Hellteh
Junior Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору king_stiven Зачем вы повторяетесь, если не поняли задачу? Убедитесь сначала хотя бы на (echo Test1&pause&echo Test2) - вполне рабочий пример для этой задачи. Ну а конкретно подойдет любая программа, выводящая множество строк в виде лога, который нужно обрабатывать в реальном времени а не дожидаясь окончания ее работы. Поясню почему вариант 1.exe>1.txt тоже не подходит: Во-первых, хотя программа и будет писать в файл в реальном времени, но если пытаться читать его командой после этой - мы его прочтем только после окончания работы программы. Конечно, есть вариант запускать программу так: start 1.exe - тогда выполнение нашего батника продолжится параллельно с программой и мы сможем читать лог параллельно, однако тут возникают аж три лишних сущности-проблемы: 1) нужно постоянно перечитывать лог на предмет появления новых строк (а если лог в сотни тысяч строк?) 2) нужно определять на каких строках мы закончили в прошлое перечитывание 3) нужно определять что приложение завершилось (это не всегда очевидно из ее вывода) Конечно, все они решаемы, но зачем городить такой огород костылей, если мой костыль гораздо короче, проще, надежней и наконец значительно быстрее для крупных логов? И наконец, появляется четвертая проблема, про которую я не сразу вспомнил, достаточно серьезная: 4) Файл 1.txt на время работы программы будет заблокирован! И недоступен для чтения командами вроде for /f. Во-вторых, в таком варианте создается дополнительный лишний файл, а может потребоваться работа в ситуации "только для чтения". А я, раз уж заговорил про VBScript, то окончательно завершу тему тремя вариантами обработки на нем. Пример с запуском обрабатываемой программы внутри скрипта на VBScript, показаны все три варианта: Код: Dim objShell, objExec, objExecHandler, objRegExp Dim strOutLine, strPath Set objRegExp = CreateObject("VBScript.RegExp") 'Создаем объект работы с регулярными выражениями objRegExp.Pattern = "Test(1|2)" 'Задаем шаблон для отсева строк 'Путь к этому скрипту (подразумевается, что рядом с ним лежит handler.cmd - обработчик строк) strPath = Left(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName, "\", -1, 1)) Set objShell = WScript.CreateObject("WScript.Shell") Set objExec = objShell.Exec("%ComSpec% /c echo Test1&echo Test2") 'Обрабатываемая команда/программа Do strOutLine = objExec.StdOut.ReadLine 'Вариант обработки внутри VBScript If InStr(strOutLine, "Test1") > 0 Then WScript.StdOut.WriteLine "1" ElseIf InStr(strOutLine, "Test2") > 0 Then WScript.StdOut.WriteLine "2" End If 'Варианты обработки во внешнем батнике If objRegExp.Test(strOutLine) Then 'В новом консольном окне с ожиданием завершения обработчика objShell.Run "%ComSpec% /c " & strPath & "handler.cmd """ & strOutLine & """", 1, True 'В скрытом консольном окне с перенаправлением вывода в текущую консоль, в которой запущен VBScript, 'сначала собрав весь вывод обработчика Set objExecHandler = objShell.Exec("%ComSpec% /c " & strPath & "handler.cmd """ & strOutLine & """") WScript.StdOut.Write(objExecHandler.StdOut.ReadAll) WScript.StdErr.Write(objExecHandler.StdErr.ReadAll) End If Loop While Not objExec.StdOut.AtEndOfStream | Запускать этот скрипт в батнике как обычно: cscript test.vbs //b %ComSpec% /c echo Test1&echo Test2 - пример обрабатываемой команды, вместо нее подставьте полный путь к вашей программе, если она лежит рядом со скриптом то можно так: strPath & "program.exe" Пример (echo Test1&echo Test2) без pause ибо на нее пользователь не сможет ответить в таком запуске программы/команды из VBScript, если нужно отвечать на сообщения программы - переписывайте скрипт под вариант запуска program.exe|cscript test.vbs //b - вместо чтения objExec.StdOut нужно будет читать WScript.StdIn, можно тем же ReadLine (т.е. просто замените все objExec.StdOut на WScript.StdIn и удалите строку Set objExec = блабла). В скрипте показано 3 варианта обработки вывода, используйте только нужный выкинув все остальные и их переменные. Но есть нюанс: к сожалению я не нашел, как при запуске команды по cmd /c указать в кавычках и путь к handler.cmd (если он содержит пробелы) и первый аргумент - в таком случае cmd обрабатывал команду неверно, правильно работает только для одной пары кавычек (ключ /s не помог), поэтому я оставил кавычки только для передаваемой строки, т.ч. путь к скрипту/handler.cmd должен быть без пробелов и спецсимволов! | Всего записей: 111 | Зарегистр. 15-03-2009 | Отправлено: 00:44 29-01-2013 | Исправлено: Hellteh, 02:12 29-01-2013 |
|