Что нового

Как написать консольное приложение Stdin/Stdout

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
Версия AutoIt:3.

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

Код:
Func _Msg($index,$title,$text)
    MsgBox($index,$title,$text)
EndFunc


Как передать параметры с главного скрипта в консольное и вызвать эту функцию?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 473
Репутация
2 403
Как то так:

Main.au3:
Код:
$iPid = Run("Console.exe", "", @SW_HIDE, 1)
Sleep(1500)
StdinWrite($iPid, '/Func:_Msg(64, "Title", "Hi")')
Sleep(3000)
StdinWrite($iPid, '/Exit')


Console.exe:
Код:
$sRead = ""

While 1
	Sleep(10)
	
	$sRead &= ConsoleRead()
	;If @error Then exit
	
	If $sRead Then
		If StringLeft($sRead, 6) = "/Func:" Then
			Execute(StringTrimLeft($sRead, 6))
		ElseIf $sRead = "/Exit" Then
			Exit
		EndIf
		
		$sRead = ""
	EndIf
WEnd

Func _Msg($index,$title,$text)
    MsgBox($index,$title,$text)
EndFunc


Кстати, оно будет работать и с обычным скриптом, не консольным.
 
Автор
S

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
Спасибо,работает,то что нужно,и зачем теперь нужны DLL'ки :laugh:
 
Автор
S

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
Я это уже смотрел,но не всё понял,захотел разобраться на простом примере... :smile:
 
Автор
S

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
Классная вешь, поставил расширение dll ,через редактор ресурсов применил "Статическая библиотека" и всё равно работает,теперь можно dll'ки делать,правдо вызывать функции из неё не обычным способом нужно ;D
 

VladUs

Скриптер
Сообщения
621
Репутация
180
Sergey2210 [?]
поставил расширение dll
Скажу Вам по секрету. С таким успехом можно любой UDF превратить в dll.
Достаточно создать свой UDF c функциями, дать ему расширение .dll (хоть .jpg),
подключайте эту библиотеку к основному скрипту и вызывай из нее необходимые функции.
 
Автор
S

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
Это я знаю,но после компиляции скрипта,вашу UDF можно будет выбросить в корзину,так как всё её содержимое будет находится в главном скрипте....
 

zlo-kazan

Скриптер
Сообщения
374
Репутация
100
Можно изменить подход. Можно не отправлять команды скрипту, а можно сделать, чтобы скрипт искал главную часть и следил за ней.
Где-то видел функцию которая работает на подобии GUIGetMsg, только для чужого GUI... т.е. в консольный скрипт можно её встроить и он будет следить на нажатиями в главном скрипте...

P.S. обсуждалось примерно в последние 2 недели, но найти не могу :search:
 
Автор
S

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
Было бы не плохо...
 
Автор
S

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
Не знаю,но я понял так,что главный скрипт никуда ничего не отправляет,а в консольное приложение добавляется какая то доп.функция для контроля главного скрипта и все действия считываются в консольное приложение ...
 

zlo-kazan

Скриптер
Сообщения
374
Репутация
100
Хм... ту функцию не нашел, нашел немного другое. :smile: Читает Lable главного окна.

Если ввести test... выдаст значение lable главного окна... если ввести ping выдаст пинг до yandex.ru
Консольная часть ждущая команды.
Код:
$command1="test"
$command2="ping"
While 1
If ControlGetText("My GUI","","[CLASS:1; ID:5]")=$command1 then 
	command1()
ElseIf ControlGetText("My GUI","","[CLASS:1; ID:5]")=$command2 Then
	_ping()
EndIf
	sleep(100)

WEnd


Func command1() 
	msgbox(0,"",ControlGetText("My GUI","","[CLASS:1; ID:5]"))
EndFunc

Func _ping()
	msgbox(0,"","ping yandex.ru" & @CRLF & ping("yandex.ru") & " ms")
EndFunc


GUI часть откуда берется команда
Код:
#include <GUIConstants.au3>

GUICreate("My GUI", 200, 200)  ; will create a dialog box that when displayed is centered
$input=GUICtrlCreateInput("",10,10, 180,30)
$button=GUICtrlCreateButton("Применить", 90, 50, 100,30)
$text=GUICtrlCreateLabel("",10, 100, 180,100)
GUISetState (@SW_SHOW)       ; will display an empty dialog box

; Run the GUI until the dialog is closed
$Timer=TimerInit()
While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
	switch $msg
		Case $button
		GUICtrlSetData($text,GUICtrlRead($input))
		$timer=TimerInit()
	EndSwitch
	If TimerDiff($timer)>1000 then 
		GUICtrlSetData($text," ")
		$timer=TimerInit()
	EndIf
Wend
 

Pelerin

Осваивающий
Сообщения
81
Репутация
23
Если задача стоит в том чтобы создать полноценное консольное приложение и GUI к нему то можно истользовать $cmdline (или $cmdlineraw) в консольном скрипте, и Run или Shellexecute в скрипте-GUI.
Как пример мой total_config
 
Автор
S

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
А как передать из консольного приложения в главное результат выполнения какой либо функции,пробовал через ConsoleWrite/ConsoleRead,Stderr/ConsoleWriteErr
 

zlo-kazan

Скриптер
Сообщения
374
Репутация
100
Ещё осталось попробовать ControlSetText
GUI часть
Код:
#include <GUIConstants.au3>
GUICreate("My GUI", 200, 200)  ; will create a dialog box that when displayed is centered
$input=GUICtrlCreateInput("",10,10, 180,30)
$button=GUICtrlCreateButton("Применить", 90, 50, 100,30)
$text=GUICtrlCreateLabel("",10, 100, 180,100)
GUISetState (@SW_SHOW)       ; will display an empty dialog box

; Run the GUI until the dialog is closed
$Timer=TimerInit()
While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
	switch $msg
		Case $button
		GUICtrlSetData($text,GUICtrlRead($input))
		$timer=TimerInit()
	EndSwitch
	If TimerDiff($timer)>1000 then 
		GUICtrlSetData($text," ")
		$timer=TimerInit()
	EndIf
Wend


Консольная часть
Код:
$command1="test"
$command2="ping"
While 1
If ControlGetText("My GUI","","[CLASS:1; ID:5]")=$command1 then 
	command1()
ElseIf ControlGetText("My GUI","","[CLASS:1; ID:5]")=$command2 Then
	_ping()
EndIf
	sleep(100)
	
WEnd


Func command1() 
	ControlSetText("My GUI","","[CLASS:1; ID:3]",'Команда "command1" выполнена')
	msgbox(0,"",ControlGetText("My GUI","","[CLASS:1; ID:5]"))
EndFunc

Func _ping()
	ControlSetText("My GUI","","[CLASS:1; ID:3]",'Команда "_ping" выполнена')
	msgbox(0,"","ping yandex.ru" & @CRLF & ping("yandex.ru") & " ms")
EndFunc


Добавлено:
Сообщение автоматически объединено:

Сделал общение через ControlSetText. Только у консольной части сделал скрытый GUI в котором есть lable который ждет когда в него, что-нибудь пропишут. Теперь можно из любой программы отсылать команды. :smile:

GUI
Код:
#include <GUIConstants.au3>

GUICreate("My GUI", 200, 200)  ; will create a dialog box that when displayed is centered
$input=GUICtrlCreateInput("",10,10, 180,30)
$button=GUICtrlCreateButton("Применить", 90, 50, 100,30)
$text=GUICtrlCreateLabel("",10, 100, 180,100)
GUISetState (@SW_SHOW)       ; will display an empty dialog box


While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
	switch $msg
		Case $button
		ControlSetText("GUI2","","[CLASS:1; ID:3]",GUICtrlRead($input))
	EndSwitch
Wend


Консольная
Код:
#include <GUIConstants.au3>

GUICreate("GUI2", 0, 0)  
$text=GUICtrlCreateLabel("",0 ,0, 0,0)
GUISetState (@SW_HIDE)       
GUICtrlSetData($text,"Wait...")

$command1="test"
$command2="ping"
While 1
If GUICtrlRead($text)=$command1 then 
	command1()
ElseIf GUICtrlRead($text)=$command2 Then
	_ping()
ElseIf GUICtrlRead($text)="Wait..." Then
	sleep(5)
Else
	ControlSetText("My GUI","","[CLASS:1; ID:3]",'неизвестная команда')
	GUICtrlSetData($text,"Wait...")
EndIf
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
	sleep(5)
WEnd


Func command1() 
	ControlSetText("My GUI","","[CLASS:1; ID:3]",'Команда "command1" выполнена')
	msgbox(0,"",ControlGetText("My GUI","","[CLASS:1; ID:3]"))
	GUICtrlSetData($text,"Wait...")
EndFunc

Func _ping()
	ControlSetText("My GUI","","[CLASS:1; ID:3]",'Команда "_ping" выполнена')
	msgbox(0,"","ping yandex.ru" & @CRLF & ping("yandex.ru") & " ms")
	GUICtrlSetData($text,"Wait...")
EndFunc






Добавлено:
Сообщение автоматически объединено:

Интересная штука получилась... :scratch: если нормально оформить в функцию, то решает вопрос о многопоточности AutoIt... :IL_AutoIt_1:
 
Автор
S

Sergey2210

Осваивающий
Сообщения
263
Репутация
31
у меня получается отправить через ConsoleWrite результат выполнения функции в главный скрипт,но вытянуть текс из консоли почему то не могу...

Главный скрипт:
Код:
PluginCall("ex.exe",'_Msg(64, "Title", "Hi")')

Func PluginCall($hFile,$hFunc)
	Local $sRead = ""
    $iPid = Run($hFile, "", @SW_HIDE, 1)
    StdinWrite($iPid, '/Func:'& $hFunc)
	Sleep(1000)
    StdinWrite($iPid, '/Exit')
EndFunc

Скрипт консольного приложения:
Код:
$sRead = ""

While 1
    Sleep(10)
    
    $sRead &= ConsoleRead()
    ;If @error Then exit
    
    If $sRead Then
        If StringLeft($sRead, 6) = "/Func:" Then
            Execute(StringTrimLeft($sRead, 6))
        ElseIf $sRead = "/Exit" Then
            Exit
        EndIf
        
        $sRead = ""
    EndIf
WEnd

Func _Msg($index,$title,$text)
    MsgBox($index,$title,$text)
	If @error Then 
	    ConsoleWrite("0" & @CRLF)
	Else	
	    ConsoleWrite("1" & @CRLF)
	EndIf	
EndFunc
 

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
410
Я извиняюсь если не туда написал и нужно было создавать новую тему,но по моему она подходит для моего вопроса, я посмотрел примеры в этой теме и ни как не могу разобраться...

1. Как написать консольное приложение чтоб после компиляции его открыть и там можно было писать,а после нажатия Enter эта строка считалась с консоли
2. Например приложение находится в покое,берём файл мышкой,переносим на сам exe и программа открывается с выведенным путём до этого файла,который мы переместили.

Конечно если AutoIt такое поддерживает.

Код:
$sRead = ""

While 1
	Sleep(10)
	
	$sRead &= ConsoleRead()
	If $sRead Then
		; Тут код который выполняет определённую
		; функцию, смотря что будет в консоле
		; это не нужно писать...
	    $sRead = ""
    EndIf
	
WEnd
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
Viktor1703,
1. Не совсем понял, что надо.
2.
Код:
If Not $CmdLine[0] Then
	MsgBox(16, 'Error', 'Error')
Else
	MsgBox(64, 'Info', $CmdLine[1])
EndIf
 

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
410
На основе первого примера сделать что-то похожее на cmd.exe , в котором можно писать текст и выводит полный путь до файла если его переместить в саму консоль, после того как сделал не большую функцию с выводом введённых данных в MsgBox()
я скомпилировал скрипт для проверки(при компиляции поставил галку консоль) и открыл,решил вписать текст а он не пишется,каретка не уходит,стоит на месте(опыт закончился не удачей)
 
Верх