Что нового

Как запустить программу с ключом?

ivsatel

Продвинутый
Сообщения
319
Репутация
84
Здравствуйте.
Использую AutoIt: v.3.3.8.1
Подскажите как реализовать запуск программы с ключом.
Т.е. к примеру если программу добавить в автозагрузку
Код:
HKLM\...\RUN\start.exe
то просто запустится программа. А я хотел бы реализовать
Код:
HKLM\...\RUN\start.exe /D1
и т.д.
При задании ключа программа запускалась бы сразу с определенным заданием.

Решение http://autoit-script.ru/index.php?topic=4125.0
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
ivsatel
Вот моя концепция обработки параметров. Пример взят из утилиты "Process", но принцип использую и в других (TextReplace, create_lnk и т.д.)
При таком способе можно указывать или не указывать префиксы-имена параметров, и очерёдность параметров не имеет значения. Кстати, в TextReplace используются "префиксы-имена".

Код:
; Для теста создайте ярлык к этому файлу и в продолжении командной строки укажите параметры: число, путь (в кавычках), help, f (независимо от регистра).
#include <Array.au3>

$spr = Chr(1) ; выбираем разделитель который не может использоваться в ком-строке (непечатный символ)
$Esc = '[\\/-]?' ; набор допустимых экранирующих символов в параметрах, например \10, /10, -10, знак "?" разрешает отсутствие символа
Switch $CmdLine[0]
	Case 1 To 3 ; определяем количество параметров которое является валидным
		; отправляем массив параметров в строку, как раньше, но разделяя специальным разделителем, который легче парсить.
		$ParamLine = $spr & _ArrayToString($CmdLine, $spr, 1) & $spr
		
		; ищем число, например 3000
		$aTmp = StringRegExp($ParamLine, $spr & $Esc & '(\d+?)' & $spr, 3)
		If Not @error And UBound($aTmp) = 1 Then ; если нет ошибок (найдено) и если найден 1 (а не 2 однотипных параметра), то
			$cmd_Timer = $aTmp[0] ; валидация прошла успешно и передаем найденный параметр специальной переменной
			MsgBox(0, 'Число', $cmd_Timer)
		Else
			MsgBox(0, 'Ошибка', 'Не найдено число') ; иначе сообщение об ошибке
			; Exit ; и выход... если сама утилита используется в ком-строке, то тут можно указать код выхода (без MsgBox)
		EndIf

		; ищем путь, например C:\
		$aTmp = StringRegExp($ParamLine, $spr & $Esc & '([a-zA-Z]:\\[^/:*?"<>|' & $spr & ']+[^.\\' & $spr & '])' & $spr, 3)
		If Not @error And UBound($aTmp) = 1 Then ; если найден только 1 параметр, то
			If FileExists($aTmp[0]) Then ; проверяем что путь существует
				$cmd_Path = $aTmp[0] ; назначаем переменной при успехе
				MsgBox(0, 'Путь', $cmd_Path)
			Else
				MsgBox(0, 'Ошибка', 'Путь не существует.') ; сбой, параметры неверны
				; Exit
			EndIf
		Else
			MsgBox(0, 'Ошибка', 'Не указан путь или указано более одного') ; сбой, параметры неверны
			; Exit ; выход закомментирован для нормальной работы примера
		EndIf
		
		; ищем один из двух ключей "?" или "help"
		$aTmp = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(\?|help)' & $spr, 3)
		If Not @error And UBound($aTmp) = 1 Then
			MsgBox(0, 'Сообщение', 'Это пример демонстрирующий обработку ком-строки')
		EndIf
		
		; ищем ключ f
		$aTmp = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(f)' & $spr, 3)
		If Not @error And UBound($aTmp) = 1 Then $cmd_f = 1
		
		; здесь может быть вызов функции или продолжить скрипт, зависит от построения конструкции
EndSwitch
 
Автор
I

ivsatel

Продвинутый
Сообщения
319
Репутация
84
Код:
#Include <Array.au3>

;Если ни чего не выбрано то продолжаем выполнение основного скрипта
If $CmdLine[0] = 0 Then

EndIf

; реакция на параметры
Switch $CmdLine[0]
	Case "r"
		MsgBox('', '', 'Клавиша R')
    Case "t"
        MsgBox('', '', 'Клавиша T')
    Case "s"
        MsgBox('', '', 'Клавиша S')
    Case "x"
        MsgBox('', '', 'Клавиша X')
EndSwitch

;основной срипт
MsgBox('', '', '1')
MsgBox('', '', '2')
MsgBox('', '', '3')

Что то не могу до конца понять принцип действия.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Чем не подходит _CmdLineSetEvent?

ivsatel [?]
Что то не могу до конца понять принцип действия.
А что тут понимать, $CmdLin[0] не содержит параметров, он содержит число переданных параметров.
Дали же несколько примеров, в чём проблема их использовать?
 
Автор
I

ivsatel

Продвинутый
Сообщения
319
Репутация
84
Дали же несколько примеров, в чём проблема их использовать?
Я попытался сам сделать из того что я понял. Видимо ни чего не понял :stars:
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
ivsatel
Думаю вам будет понятен такой пример. Передавайте параметр и смотрите массив.

Код:
#include <Array.au3>
_ArrayDisplay($CmdLine, 'массив передаваемых параметров')
 
Автор
I

ivsatel

Продвинутый
Сообщения
319
Репутация
84
Спасибо! Действительно стало понятней :laugh:
Вот что получилось:

Код:
#include <Array.au3>

;цикл ловли параметров

If $CmdLine[0] > 0 Then
    Switch $CmdLine[1]
        Case "1"
            out("1")
        Case "2"
            out("2")
        Case "3"
            out("3")
        Case "4"
            out("4")
        Case Else
            out("Параметр не известен!")
	EndSwitch
Exit
Else
    MsgBox(0, "Info", "Запуск без параметров --> Продолжаю основной скрипт", 4)
EndIf

;функция для цикла
Func out($txt)
    MsgBox(0, "Info", $txt)
EndFunc   ;==>out

;продолжить основной срипт если нет параметров запуска
MsgBox('', '', '1')
MsgBox('', '', '2')
MsgBox('', '', '3')
 
Автор
I

ivsatel

Продвинутый
Сообщения
319
Репутация
84
AZJIO
На Вашем примере попробовал внедрить в скрипт. Скрипт с наличием гуи. Структура такая:
Код:
;Переменные
;Отображение ГУИ
;Цикл обработки команд (выбранных чекбоксов)
;Функции первого окна
_1()
_2()
~
_13()
;Функции второго окна
_L1()
_L2()
_L3()
~
_L13()

Ваш пример я разместил в начале скрипта (до переменных). Но почему возникает ошибка "Variable used without being declared"
Код:
;Запуск из консоли с параметрами

$spr = Chr(1) ; выбираем разделитель который не может использоваться в ком-строке (непечатный символ)
$Esc = '[\\/-]?' ; набор допустимых экранирующих символов в параметрах, например \10, /10, -10, знак "?" разрешает отсутствие символа
Switch $CmdLine[0]
    Case 1 To 13 ; определяем количество параметров которое является валидным
        ; отправляем массив параметров в строку, как раньше, но разделяя специальным разделителем, который легче парсить.
        $ParamLine = $spr & _ArrayToString($CmdLine, $spr, 1) & $spr

        ; ищем ключ Dr
        $aTmpDr = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(Dr)' & $spr, 3)
        If Not @error And UBound($aTmpDr) = 1 Then $cmd_dr = _1()

		; ищем ключ Ka
        $aTmpKa = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(Ka)' & $spr, 3)
        If Not @error And UBound($aTmpKa) = 1 Then $cmd_ka = _2()

		; ищем ключ Mb
        $aTmpMb = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(Mb)' & $spr, 3)
        If Not @error And UBound($aTmpMb) = 1 Then $cmd_mb = _3()

        ; здесь может быть вызов функции или продолжить скрипт, зависит от построения конструкции
EndSwitch

Я вообще правильно использую данный пример?
Основная идея, это вызов функции из скрипта с использованием командной строки без отображения ГУИ.
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
ivsatel
Я вообще правильно использую данный пример?
Правильно. Если функции ничего не возвращают, то можно не приравнивать к переменной. Перед EndSwitch наверно должна быть команда Exit. Код в начало скрипта вставить.
Незря значит я пример на досуге улучшил, уже после ответов.
 
Автор
I

ivsatel

Продвинутый
Сообщения
319
Репутация
84
AZJIO
Если использовать
Код:
Exit
то программа просто вылетает.
Если не использовать
Код:
Exit
то программа просто запускается.
Не пойму в чем дело. Ведь если этот скрипт использовать отдельно то все прекрасно работает.
Код:
;Запуск из консоли с параметрами

$spr = Chr(1) ; выбираем разделитель который не может использоваться в ком-строке (непечатный символ)
$Esc = '[\\/-]?' ; набор допустимых экранирующих символов в параметрах, например \10, /10, -10, знак "?" разрешает отсутствие символа

Switch $CmdLine[0]
	Case 1 To 13 ; определяем количество параметров которое является валидным
        ; отправляем массив параметров в строку, как раньше, но разделяя специальным разделителем, который легче парсить.
        $ParamLine = $spr & _ArrayToString($CmdLine, $spr, 1) & $spr

        ; ищем ключ Dr
        $aTmpDr = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(Dr)' & $spr, 3)
        If Not @error And UBound($aTmpDr) = 1 Then _1()

        ; ищем ключ Ka
        $aTmpKa = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(Ka)' & $spr, 3)
        If Not @error And UBound($aTmpKa) = 1 Then _2()

        ; ищем ключ Mb
        $aTmpMb = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(Mb)' & $spr, 3)
        If Not @error And UBound($aTmpMb) = 1 Then _3()

        ; здесь может быть вызов функции или продолжить скрипт, зависит от построения конструкции
	Exit
EndSwitch
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
ivsatel
то программа просто вылетает.
Так и должно быть. Использование командной строки позволяет в фоне выполнить все необходимые функции, которые бы задавались чекбоксами. То есть все настройки передаются через ком-строку, после обработки программа завершает свою работу.
К тому же отсутствует выход при неправильно заданных командах. Из скрипта видно, что если не найден какой то ключ, скрипт продолжает обрабатывать другие ключи. Такой вариант возможен, но без понятия что требуется сложно что-то советовать.
В правильной программе на каждый ключ идёт своя обработка валидности и если что то пошло не так, то высылается Exit с параметром, например "Exit 2" который возвращается например в cmd-файл в виде переменной %ERRORLEVEL%, что определяет ошибку в передаваемых параметрах, подробнее в справке по Exit.
И обычно сначала я передаю состояние параметров в переменныю чтобы определить валидность параметров, а уж потом отправляю в функцию. Если сразу вызывать функции, то при отсутвии нужного параметра какая нибудь функция не сработает, отсюда и ошибки (если функции взаимосвязаны).
 
Автор
I

ivsatel

Продвинутый
Сообщения
319
Репутация
84
AZJIO
Спасибо за ответ! Стало еще понятней. Получается, что-бы функция отработала (на моем скрипте) она должна быть самодостаточной, т.е. все переменные определяются в ней. И тогда она отрабатывает.
А по поводу выхода из
Код:
Switch
я создал в конце условие с
Код:
Exit

Код:
; ищем ключ Exit
        $aTmpExit = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(Exit)' & $spr, 3)
        If Not @error And UBound($aTmpExit) = 1 Then
			Exit
		Else
			Exit
		EndIf

Тогда, по завершении всех заданий заказанных через параметры, программа закрывается, а если без параметров, то просто запускается графический интерфейс.
Еще раз спасибо.
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
ivsatel
На офсайте появилась UDF GetOpt.au3 для получения параметров командной строки. Как я понял из описания есть некоторый стандарт.
 
Автор
I

ivsatel

Продвинутый
Сообщения
319
Репутация
84
Код:
#include <INet.au3>
#Include <Array.au3>

$spr = Chr(1) ; выбираем разделитель который не может использоваться в ком-строке (непечатный символ)
$Esc = '[\\/-]?' ; набор допустимых экранирующих символов в параметрах, например \10, /10, -10, знак "?" разрешает отсутствие символа
Switch $CmdLine[0]

    Case 1 To 4 ; определяем количество параметров которое является валидным
        ; отправляем массив параметров в строку, как раньше, но разделяя специальным разделителем, который легче парсить.
        $ParamLine = $spr & _ArrayToString($CmdLine, $spr, 1) & $spr

        ; ищем ключ для HijackThis
        $aTmp = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(1)' & $spr, 3)
        If Not @error And UBound($aTmp) = 1 Then
			_1()
		EndIf

		; ищем ключ 2
        $aTmp = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(2)' & $spr, 3)
        If Not @error And UBound($aTmp) = 1 Then
			_2()
		EndIf

		; ищем ключ 3
        $aTmp = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(3)' & $spr, 3)
        If Not @error And UBound($aTmp) = 1 Then
			_3()
		EndIf

		; ищем ключ 4
        $aTmp = StringRegExp($ParamLine, '(?i)' & $spr & $Esc & '(exit)' & $spr, 3)
        If Not @error And UBound($aTmp) = 1 Then			
			Exit
		EndIf
Exit
EndSwitch

Func _1()
	;Переменные для HijackThis
Global $MirAdHi = 'http://citylan.dl.sourceforge.net/project/hjt/'
Global $URLHi = _INetGetSource('http://sourceforge.net/projects/hjt/')
Global $HiName = StringRegExp($URLHi, '[\<]a href[\=]"/projects/hjt/files/latest/download" title="Download /(.*?) from SourceForge', 3)

If @error Then
    MsgBox(48+262144, 'Error', 'Загрузка утилиты HijackThis не возможна', 5)
Global $HiLink = @error
Else
Global $HiLink = $MirAdHi & $HiName[0]
EndIf

Global $hDHi = InetGet($HiLink, @ScriptDir & '\HijackThis.exe', 1, 0)
Do
InetGetInfo($hDHi, 1)
Until InetGetInfo($hDHi, 2)
InetClose($hDHi)
Sleep(1000)
if InetGetSize($HiLink, 1) <> FileGetSize(@ScriptDir & '\HijackThis.exe') Then
			_1()
EndIf
EndFunc

Func _2()
	MsgBox('', '', '2')
EndFunc

Func _3()
	MsgBox('', '', '3')
EndFunc

MsgBox('', '', 'Запуск без параметров')

Что не так с функцией _1() Вернее чем она отличается от остальных. Может из-за наличия цикла Do
Почему висит скрипт при её выборе :stars: . Вернее не висит, а не заканчивает работу. Ведь все остальное отрабатывает нормально.
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
ivsatel
Скрипт может висеть из-за рекурсии. Функция _1() возможно вызывает саму себя, при срабатывании неравенства опять вызывает саму себя просто углубляясь в рекурсивный вызов.
 
Верх