Что нового

Вызов функции с параметрами из файла (AutoIt3ExecuteScript)

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Пытался сделать, пока добился только этого:

Скрипт:
Код:
Global $MsgBoxFunc
AU3ExecuteScript(@ScriptDir & "\Script.txt")
Execute($MsgBoxFunc)

Func AU3ExecuteScript($iScript)
	Run('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $iScript & '"')
EndFunc


Файл:
Код:
$MsgBoxFunc = Msg(32, "Example", "AutoIt3ExecuteScript")

Func Msg($Param1, $Param2, $Param3)
    MsgBox($Param1, $Param2, $Param3)
EndFunc

как вызвать данную функция непосредственно из скрипта с параметрами? и желательно с возможностью возвращения значения выполнения скрипта....
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Мне не обязательно компилировать скрипт в котором находится функция, просто нужно вызвать её из файла с параметрами, а файл выглядит так:

Код:
Func Msg($Param1, $Param2, $Param3)
    MsgBox($Param1, $Param2, $Param3)
EndFunc

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


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

Вызов функции с параметрами я разобрался как сделать, большое спасибо madmasles за пример в теме Работа с параметрами вида : "*.exe/.com" test, но вот как вернуть значение выполнения функции, то есть функция после выполнения должна вернуть какое то значение, как его поймать главным сриптом?

Скрипт:
Код:
Global $Calling[4] = ['Msg', 32, 'Example', 'AutoIt3ExecuteScript']

AU3ScriptExecute(@ScriptDir & "\Script.txt", $Calling)

Func AU3ScriptExecute($iScript, $ArrayParam)
	Local $CallFunc
	
	If IsArray($ArrayParam) Then
	    For $i = 0 To UBound($ArrayParam) - 1
            $CallFunc &= ' "' & $Calling[$i] & '"'
        Next
	
	    If $iScript <> "" Then
			If @Compiled Then
			    Run('"' & @ScriptFullPath & '" /AutoIt3ExecuteScript "' & $iScript & '"' & $CallFunc)
	        Else	
	            Run('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $iScript & '"' & $CallFunc)
	        EndIf
		    Return 1
	    Else 
            Return 0		
	    EndIf	
	EndIf
	
EndFunc


Внешний файл:
Код:
If $CmdLine[0] Then
    If $CmdLine[1] = "Msg" Then Msg($CmdLine[2], $CmdLine[3], $CmdLine[4])
EndIf

Func Msg($Param1, $Param2, $Param3)
    MsgBox($Param1, $Param2, $Param3)
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,320
Viktor1703,
Попробуйте примерно так, у меня работает.
file_to_run.au3:
Код:
#NoTrayIcon
If $CmdLine[0] <> 3 Then
	ConsoleWrite('Error CmdLine')
	Exit
EndIf
ConsoleWrite(_MyFunc($CmdLine[1], $CmdLine[2], $CmdLine[3]))
Func _MyFunc($i_First, $i_Second, $i_Third)
	Return Number($i_First) * Number($i_Second) * Number($i_Third)
EndFunc   ;==>_MyFunc

Запускаем его скриптом (можно скомпилированным):
Код:
#include <Constants.au3>

$sFile = @ScriptDir & '\file_to_run.au3'
$i1 = Random(10, 100, 1)
$i2 = Random(10, 100, 1)
$i3 = Random(10, 100, 1)

$sReturn = _AutoIt3ExecuteScript($sFile, $i1, $i2, $i3)
MsgBox(64, 'Info', StringFormat('%d * %d * %d = %d\nFrom Func: %s', $i1, $i2, $i3, $i1 * $i2 * $i3, $sReturn))

Func _AutoIt3ExecuteScript($s_FilePath, $i_First, $i_Second, $i_Third)
	Local $i_Pid, $s_Run = '"' & @AutoItExe & '" /AutoIt3ExecuteScript', $s_Read, $i_Start
	If Not FileExists($s_FilePath) Then Return 'Not File'
	$s_Run &= ' "' & $sFile & '" "' & $i_First & '" "' & $i_Second & '" "' & $i_Third & '"'
	$i_Pid = Run($s_Run, '', @SW_HIDE, $STDOUT_CHILD)
	If Not $i_Pid Then Return 'Not PID'
	$i_Start = TimerInit()
	While TimerDiff($i_Start) <= 2000
		$s_Read &= StdoutRead($i_Pid)
		If @error Then ExitLoop
		Sleep(10)
	WEnd
	If ProcessExists($i_Pid) Then ProcessClose($i_Pid)
	If $s_Read Then Return $s_Read
	Return 'Nothing'
EndFunc   ;==>_AutoIt3ExecuteScript
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Вот сделал так:

Скрипт:
Код:
#include <Constants.au3>

Global $Calling[4] = ["Msg", 32, "Example", "AutoIt3ExecuteScript"]

MsgBox(0, '', AutoIt3ExecuteScript(@ScriptDir & "\Script.txt", $Calling))

Func AutoIt3ExecuteScript($iScript, $ArrayParam)
	Local $CallFunc, $iPid, $iRead, $iStart = TimerInit()
	
	If IsArray($ArrayParam) Then
	    For $i = 0 To UBound($ArrayParam) - 1
            $CallFunc &= ' "' & $Calling[$i] & '"'
        Next
	
	    If $iScript <> "" Then
			If @Compiled Then
			    $iPid = Run('"' & @ScriptFullPath & '" /AutoIt3ExecuteScript "' & $iScript & '"' & $CallFunc, "", @SW_HIDE, $STDOUT_CHILD)
	        Else	
	            $iPid = Run('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $iScript & '"' & $CallFunc, "", @SW_HIDE, $STDOUT_CHILD)
	        EndIf
			
			If $iPid Then
			    While TimerDiff($iStart) <= 2000
                    $iRead &= StdoutRead($iPid)
                    If @error Then ExitLoop
                    Sleep(10)
			    WEnd
			    If $iRead Then Return $iRead
			Else
			    Return 0	
			EndIf	
	    Else 
            Return 0		
	    EndIf	
	EndIf
	
EndFunc

Файл с функцией:
Код:
If $CmdLine[0] Then
    If $CmdLine[1] = "Msg" Then Msg($CmdLine[2], $CmdLine[3], $CmdLine[4])
EndIf

Func Msg($Param1, $Param2, $Param3)
    MsgBox($Param1, $Param2, $Param3)
    Return 1
EndFunc

Всё отлично работает, поставил проверку по первому параметру, если $CmdLine[1] = названию функции то она вызывается с параметрами, если нет то ни каких действий не происходит, но у меня не получается вернуть результат выполнения функции, пишет что в $iRead пусто и по условию в функции выводит 0
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,320
Viktor1703,
Проверку @Compiled можно не делать, в скомпилированном скрипте @AutoItExe вернет путь к скомпилированному файлу.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Спасибо за подсказку, но это не изменило результатов выполнения скрипта :smile:


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

Вроде сделал, значение возвращает но с помощью функции ConsoleWrite(1)

Вот весь пример:

Скрипт:
Код:
Global $Calling[4] = ["Msg", 32, "Example", "AutoIt3ExecuteScript"]

MsgBox(0, '', AutoIt3ExecuteScript(@ScriptDir & "\Script.txt", $Calling))

Func AutoIt3ExecuteScript($iScript, $ArrayParam)
	Local $CallFunc, $iPid, $iRead
	
	If IsArray($ArrayParam) Then
	    For $i = 0 To UBound($ArrayParam) - 1
            $CallFunc &= ' "' & $Calling[$i] & '"'
        Next

		$iPid = Run('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $iScript & '"' & $CallFunc, "", @SW_HIDE, 2)

		While TimerDiff(TimerInit()) <= 2000
			$iRead &= StdoutRead($iPid)
			If @error Then ExitLoop
			Sleep(10)
		WEnd
		
		If ProcessExists($iPid) Then ProcessClose($iPid)
		If $iRead Then Return $iRead
	EndIf
	
EndFunc

Внешний файл:
Код:
If $CmdLine[0] Then
    If $CmdLine[1] = "Msg" Then Msg($CmdLine[2], $CmdLine[3], $CmdLine[4])
EndIf

Func Msg($Param1, $Param2, $Param3)
    MsgBox($Param1, $Param2, $Param3)
    ConsoleWrite(1)
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,320
Viktor1703 [?]
значение возвращает но с помощью функции ConsoleWrite(1)
А если так?
Код:
Func Msg($Param1, $Param2, $Param3)
    ConsoleWrite(MsgBox($Param1, $Param2, $Param3))
EndFunc
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Так тоже можно :smile:, главное что работает...
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,320
Viktor1703,
Чтобы не таскать запускаемый файл, можно во временный файл писать функцию, запускать его и удалять потом.
 
Автор
V

Viktor1703

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

Уже вот не плохо получилось, скидываю пример для оценки и советов.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Как уже известно, есть такие параметры у интерпретатора как AutoIt3ExecuteScript и AutoIt3ExecuteLine, а есть ли возможность запустить скрипт таким образом:

Код:
Global $s_Script = 'Global $i_count = 0' & _
                   'While ($i_count < 1000)' & _
				   '    $i_count += 1' & _
				   'Wend' & _
				   'MsgBox(0, "", $i_count)'

Run('"' & @ScriptFullPath & '" /AutoIt3Execute... "' & $s_Script)
 

Webarion

Осваивающий
Сообщения
135
Репутация
22
Почему это не работает в скомпилированном скрипте?
Попробовал все примеры, на AutiIt3.3.14.5 в Win7


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

Нашел ответ. В версиях Autoit выше 3.3.8.1 в начале скрипта, который будет компилироваться, нужно вставить строку:

Код:
#pragma compile(AutoItExecuteAllowed, true)


В этом случае всё работает.
 

vovsla

Осваивающий
Сообщения
558
Репутация
26
Я написал функцию для подобных вещей, очень удобно когда все настройки в базе в виде Func, $Var, Value
Получаешь массив из базы и применяешь все настройки одной строкой.
Также можно выполнять массовую блокировку/разблокировку или очистку элементов, например MassCall('GUICtrlSetData', '$Input1, $Input2, $Label5')
Нужно бы еще добавить проверку на наличие вызываемой функции - IsFunc, но с этим есть небольшая проблема, по которой я создал отдельную тему
https://autoit-script.ru/index.php?topic=25871.0

Код:
Func MassCall($CallFunction, $Param1=False, $Param2='')
	If IsArray($CallFunction) Then
		$CallFunctionArr=$CallFunction
	Else
		$IDArr=StringVarsToArr($Param1)
		If Not IsArray($IDArr) Then Return SetError(1, 0, 0)
		Dim $CallFunctionArr[$IDArr[0]][3]
		For $IDNum = 1 To $IDArr[0]
			$CallFunctionArr[$IDNum-1][0]=$CallFunction
			$CallFunctionArr[$IDNum-1][1]=$IDArr[$IDNum]
			$CallFunctionArr[$IDNum-1][2]=$Param2
		Next
	EndIf

	If UBound($CallFunctionArr, 2)<>3 Then Return SetError(2, 0, 0)
	For $CDNum = 0 To UBound($CallFunctionArr)-1
		If Not IsDeclared($CallFunctionArr[$CDNum][1]) Then ContinueLoop
		Call($CallFunctionArr[$CDNum][0], Eval($CallFunctionArr[$CDNum][1]), $CallFunctionArr[$CDNum][2])
	Next

	Return True
EndFunc

Func StringVarsToArr($StringVars)
	$StringVars=StringRegExpReplace($StringVars, '[$ ]', '')
	$VarsArr=StringSplit($StringVars, ',')
	If Not IsArray($VarsArr) Then Return SetError(1, 0, False)
	If $VarsArr[0]=0 Then Return SetError(2, 0, False)
	Return $VarsArr
EndFunc
 
Верх