Что нового

Как прочитать текст из cmd?

ArtInt

Знающий
Сообщения
135
Репутация
18
Гуглил Искал по форуму, нашёл, что нужно юзать использовать StdoutRead()
Но если пытаюсь вывести msgbox'ом полученную строку, то выводит пустоту.
Просьба объяснить мне, что я не правильно делаю, как пользоваться этой функцией и рассказать о других решениях данной проблемы.

Код, в котором не выводится StdoutRead():
Код:
Opt ("SendKeyDelay",0)

Dim $CMD_PId
Dim $vCMD
Dim $sRead

$CMD_PId = Run (@ComSpec)

$vCMD = WinGetHandle('[CLASS:ConsoleWindowClass]', '')

;//Safety
	WinWait ($vCMD)
	WinActivate ($vCMD)
	WinWaitActive ($vCMD)
;//


Pr_Send ($vCMD,"cls")
Pr_Send ($vCMD,"cd C:\Users\USER\Desktop\java")
Pr_Send ($vCMD,"javac test.java")
Pr_Send ($vCMD,"java test")

$sRead = StdoutRead($CMD_PId)
msgbox (64,"Stdout Read:", $sRead)

Func Pr_Send ($handle, $param)
Dim $gotostart = true
	While ($gotostart)
		$gotostart = false
	If WinActive ($handle) then
		Send ($param&" {ENTER}")
	Else
		WinWaitActive ($handle,"",5)
		If WinActive ($handle) then
			$gotostart = True
		Else
			Return 0
		EndIf
	EndIf
	WEnd
EndFunc


Где test.java:

Код:
public class test {
	public static void main (String[] args){
		System.out.println ("Hello World!");
	}
}


P.S. Эх... Если бы не Б.8 правил...
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
пример
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
в справке то же самое ..я имею ввиду сам принцип считывания
 
Автор
A

ArtInt

Знающий
Сообщения
135
Репутация
18
joiner
Проблема ещё в том, что я не могу даже запустить скрипт, ибо библиотека WinAPIEx не входит в состав стандартных (по крайней мере, у меня её нет). В результате поиска по файловой области сайта, раздела UDF я нашёл её, выкладываемую Yashied'ом, однако ссыль битая.

Где можно скачать эту библиотеку?
 
Автор
A

ArtInt

Знающий
Сообщения
135
Репутация
18
Насколько я понимаю, за чтение текста отвечают строки

Код:
While 1
    $sBuffer = StdoutRead($iPID)
    If @error Then ExitLoop
    If $sBuffer Then
        $sRead &= $sBuffer
    EndIf
    Sleep(2)
WEnd
;$sRead = _WinAPI_OemToChar($sRead)
$sRead = StringStripCR($sRead)
$sRead = StringRegExpReplace($sRead, '((^[\n]*)|([\n]*$))', '')
$sRead = StringRegExpReplace($sRead, '[\n]{2,}', @LF)
$aRead = StringSplit($sRead, @LF)
$Lines_r = _ArrayToString($aRead, @CRLF, 1)


И в итоге, текст хранится в переменой $Lines_r.

Однако, у меня всё равно выводится пустой msgbox():

Код:
Opt ("SendKeyDelay",0)
#include <Array.au3>

Dim $CMD_PId
Dim $vCMD
Dim $sRead
Dim  $sBuffer

$CMD_PId = Run (@ComSpec)

$vCMD = WinGetHandle('[CLASS:ConsoleWindowClass]', '')

;//Safety
	WinWait ($vCMD)
	WinActivate ($vCMD)
	WinWaitActive ($vCMD)
;//


Pr_Send ($vCMD,"cls")
Pr_Send ($vCMD,"cd C:\Users\USER\Desktop\java")
Pr_Send ($vCMD,"javac test.java")
Pr_Send ($vCMD,"java test")

While 1
    $sBuffer = StdoutRead($CMD_PID)
    If @error Then ExitLoop
    If $sBuffer Then
        $sRead &= $sBuffer
    EndIf
    Sleep(2)
WEnd
$sRead = StringStripCR($sRead)
$sRead = StringRegExpReplace($sRead, '((^[\n]*)|([\n]*$))', '')
$sRead = StringRegExpReplace($sRead, '[\n]{2,}', @LF)
$aRead = StringSplit($sRead, @LF)
$Lines_r = _ArrayToString($aRead, @CRLF, 1)
msgbox (64,"Stdout Read:", $Lines_r)

Func Pr_Send ($handle, $param)
Dim $gotostart = true
	While ($gotostart)
		$gotostart = false
	If WinActive ($handle) then
		Send ($param&" {ENTER}")
	Else
		WinWaitActive ($handle,"",5)
		If WinActive ($handle) then
			$gotostart = True
		Else
			Return 0
		EndIf
	EndIf
	WEnd
EndFunc


Что я делаю\понимаю не так?
Если вместо
Код:
Pr_Send ($vCMD,"cls")
Pr_Send ($vCMD,"cd C:\Users\USER\Desktop\java")
Pr_Send ($vCMD,"javac test.java")
Pr_Send ($vCMD,"java test")


Поставить

Код:
Pr_Send ($vCMD,"echo 1")


Результат не меняется.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
ArtInt
Код:
$s_Read=''
$i_PID = Run('ipconfig', '', '', 0x2)
	While 1
		$s_Read &= StdoutRead($i_PID)
		If @error Then ExitLoop
		Sleep(1)
	WEnd
MsgBox(0,'',$s_Read )
 
Автор
A

ArtInt

Знающий
Сообщения
135
Репутация
18
sngr
А чем это отличается от того, что я написал выше?
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Код:
$i_PID = Run(@ComSpec & ' /C echo 1', '', '', 0x2)
 
Автор
A

ArtInt

Знающий
Сообщения
135
Репутация
18
sngr
хм... Работает.

Однако, нет ли другого решения данной проблемы, т.к. перечислять команды через "&" не очень удобно?
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Я не совсем понимаю что ты хочешь сделать.
Код:
Pr_Send ($vCMD,"cls")
Pr_Send ($vCMD,"cd C:\Users\USER\Desktop\java")
Pr_Send ($vCMD,"javac test.java")
Pr_Send ($vCMD,"java test")
- что это? Надо запустить javac test.java и java test?
 
Автор
A

ArtInt

Знающий
Сообщения
135
Репутация
18
sngr
Да.


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

Это возможно?
 
Автор
A

ArtInt

Знающий
Сообщения
135
Репутация
18
madmasles
Объясни мне тогда, пожалуйста, как мне реализовать следующее:

открыть консольное окно, потом туда писать команды, а в нужные моменты выводить то, что выдаёт консоль

?
 

Papazol

Новичок
Сообщения
16
Репутация
1
Задача была следующая: запустить команду, которая выполняется очень ОЧЕНЬ долго и в процессе изредка выдаёт в консоль некоторую инфу. Эту инфу надо перехватить и выдать в окне скрипта. Причём перехватить не всю целиком, как делается во всех найденных мною примерах, а в реальном времени. Для этого необходимо использовать в функции StdoutRead опцию peek=false, иначе при каждом считывании инфы она станет повторяться с самого начала. Сломал всю голову, как написать, что peek=false и binary=false, так как нигде не нашёл ни одного примера записи функции в этом виде. :stars: Вот, теперь он есть. Как всё просто, но время потеряно... Я тупой?

Код:
$conv = Run ( @ComSpec & " /c " & $command, "", @SW_HIDE, $STDERR_MERGED )
$Read= ''
While 1
	$Read = StdoutRead ( $conv, false, false )
	If @error Then ExitLoop
	If $Read <> '' Then
	     GUICtrlSetData ( $Edit, $Read & @CRLF, 1 )
	EndIf
	Sleep ( 2000 )
WEnd


Запуск команды Run c опциями, отличными от $STDERR_MERGED, не приводил к успеху. При запуске скрипта из редактора текст, выдаваемый в консоль запускаемой командой, появлялся в консоли же редактора, но не в переменной $Read. Так обидно видеть, что нужный текст ловится, но не тем, чем нужно! Это не упоминается нигде или я не нашёл?
 
Верх